Android Linear Layout - How to Keep Element At Bottom Of View?
Asked Answered
L

9

84

I have a TextView which I want to pin at the bottom of a landscape activity that is using LinearLayout with vertically arranged elements.

I have set android:gravity="bottom" on the text view, but it still likes to be just below the last element of the LinearLayout exactly what I do not want it to do.

Any suggestions?

Lesko answered 24/3, 2011 at 20:50 Comment(1)
Just remove the android:gravity="bottom" from TextView and add it to the LinearLayout. Your problem will be solved.Loosetongued
M
110

Update: I still get upvotes on this question, which is still the accepted answer and which I think I answered poorly. In the spirit of making sure the best info is out there, I have decided to update this answer.

In modern Android I would use ConstraintLayout to do this. It is more performant and straightforward.

<ConstraintLayout>
   <View
      android:id="@+id/view1"
      ...other attributes elided... />
   <View
      android:id="@id/view2"        
      app:layout_constraintTop_toBottomOf="@id/view1" />
      ...other attributes elided... />

   ...etc for other views that should be aligned top to bottom...

   <TextView
    app:layout_constraintBottom_toBottomOf="parent" />

If you don't want to use a ConstraintLayout, using a LinearLayout with an expanding view is a straightforward and great way to handle taking up the extra space (see the answer by @Matthew Wills). If you don't want to expand the background of any of the Views above the bottom view, you can add an invisible View to take up the space.

The answer I originally gave works but is inefficient. Inefficiency may not be a big deal for a single top level layout, but it would be a terrible implementation in a ListView or RecyclerView, and there just isn't any reason to do it since there are better ways to do it that are roughly the same level of effort and complexity if not simpler.

Take the TextView out of the LinearLayout, then put the LinearLayout and the TextView inside a RelativeLayout. Add the attribute android:layout_alignParentBottom="true" to the TextView. With all the namespace and other attributes except for the above attribute elided:

<RelativeLayout>
  <LinearLayout>
    <!-- All your other elements in here -->
  </LinearLayout>
  <TextView
    android:layout_alignParentBottom="true" />
</RelativeLayout>
Mariner answered 24/3, 2011 at 21:1 Comment(5)
This did resolve the issue. I am using a specific height for elements within the linear layoutLesko
If you're switching to RelativeLayout, might it be better to do away with the LinearLayout altogether, thus avoiding unnecessarily nested layouts?Atkins
For something like a layout inflated 100's or 1000's of times for a ListView, definitely. For a single layout for an Activity, it's not much of a hit. You're trading off programmer convenience for a tiny performance hit.Mariner
This doesn't work for Buttons inside a LinearLayout.Cnidus
The question was about LinearLayout. In some cases, it's much preferable to use it instead of ConstraintLayout or RelateveLayout. I think this answer should contain a solution for Linear layout first and other solutions after that as optional.Electro
H
134

You will have to expand one of your upper views to fill the remaining space by setting android:layout_weight="1" on it. This will push your last view down to the bottom.

Here is a brief sketch of what I mean:

<LinearLayout android:orientation="vertical">
    <View/>
    <View android:layout_weight="1"/>
    <View/>
    <View android:id="@+id/bottom"/>
</LinearLayout>

where each of the child view heights is "wrap_content" and everything else is "fill_parent".

Henderson answered 24/3, 2011 at 20:54 Comment(8)
How about if the elements have specific height like 40dp?Lesko
You must add width and height: <View android:layout_weight="1" android:layout_height="wrap_content" android:layout_width="wrap_content" />Reprography
This is more efficient than the accepted answer as it has only one ViewGroup.Caudal
This is amazing. I always forget this trick and end up spending forever messing with my layouts. This is just amazing. Solves world hunger.Themselves
Superior of all answers so far!Lobscouse
This should be correct answer! Not just because only one LinearLayout is used, but when you are inflating DialogFragment with needed layout design(some views should be on the bottom), this can comes handy because for some reason I received android.view.InflateException: Binary XML file line #7: ... when using RelativeLayout and everything works great when using LinearLayout.Softy
Simple and clean solution. Must be selected as the correct answer. Also proves that weights are no pushovers.Vogele
@Lesko it suppose to be the accepted answer, upper one is just work around. It also working fine even for list view items.Sterling
M
110

Update: I still get upvotes on this question, which is still the accepted answer and which I think I answered poorly. In the spirit of making sure the best info is out there, I have decided to update this answer.

In modern Android I would use ConstraintLayout to do this. It is more performant and straightforward.

<ConstraintLayout>
   <View
      android:id="@+id/view1"
      ...other attributes elided... />
   <View
      android:id="@id/view2"        
      app:layout_constraintTop_toBottomOf="@id/view1" />
      ...other attributes elided... />

   ...etc for other views that should be aligned top to bottom...

   <TextView
    app:layout_constraintBottom_toBottomOf="parent" />

If you don't want to use a ConstraintLayout, using a LinearLayout with an expanding view is a straightforward and great way to handle taking up the extra space (see the answer by @Matthew Wills). If you don't want to expand the background of any of the Views above the bottom view, you can add an invisible View to take up the space.

The answer I originally gave works but is inefficient. Inefficiency may not be a big deal for a single top level layout, but it would be a terrible implementation in a ListView or RecyclerView, and there just isn't any reason to do it since there are better ways to do it that are roughly the same level of effort and complexity if not simpler.

Take the TextView out of the LinearLayout, then put the LinearLayout and the TextView inside a RelativeLayout. Add the attribute android:layout_alignParentBottom="true" to the TextView. With all the namespace and other attributes except for the above attribute elided:

<RelativeLayout>
  <LinearLayout>
    <!-- All your other elements in here -->
  </LinearLayout>
  <TextView
    android:layout_alignParentBottom="true" />
</RelativeLayout>
Mariner answered 24/3, 2011 at 21:1 Comment(5)
This did resolve the issue. I am using a specific height for elements within the linear layoutLesko
If you're switching to RelativeLayout, might it be better to do away with the LinearLayout altogether, thus avoiding unnecessarily nested layouts?Atkins
For something like a layout inflated 100's or 1000's of times for a ListView, definitely. For a single layout for an Activity, it's not much of a hit. You're trading off programmer convenience for a tiny performance hit.Mariner
This doesn't work for Buttons inside a LinearLayout.Cnidus
The question was about LinearLayout. In some cases, it's much preferable to use it instead of ConstraintLayout or RelateveLayout. I think this answer should contain a solution for Linear layout first and other solutions after that as optional.Electro
E
66

I think it will be perfect solution:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <!-- Other views -->
    <Space
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"/>

    <!-- Target view below -->
    <View
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

</LinearLayout>
Electro answered 1/10, 2014 at 11:53 Comment(4)
It is a good solution, but only works on Level 14 API and above.Guelph
@Guelph You can also try to use empty view or layout instead of spaceElectro
Thanks! this is exactly what I needed and didn't require me to do any layout nesting. I think you have the superior answer.Vote
You are genius man !! i am wasting 2 days for this but miss something there thanks (Not use relative and component is view pager i my layout so its creating problem) -- I want to give more than one point but cantAppoggiatura
T
12

Step 1 : Create two view inside a linear layout

Step 2 : First view must set to android:layout_weight="1"

Step 3 : Second view will automatically putted downwards

<LinearLayout
android:id="@+id/botton_header"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >

    <View
    android:layout_width="match_parent"
    android:layout_height="0dp"
    android:layout_weight="1" />

    <Button
    android:id="@+id/btn_health_advice"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"/>


</LinearLayout>
Torr answered 24/9, 2014 at 5:36 Comment(0)
G
12

You should put the parameter gravity to bottom not in the textview but in the Linear Layout. Like this:

<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:gravity="bottom|end">
    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Something"/>
</LinearLayout>
Graz answered 3/7, 2015 at 10:33 Comment(0)
C
1

You can also use

android:layout_gravity="bottom"

for your textview

Carbine answered 25/11, 2016 at 11:33 Comment(0)
R
1

DO LIKE THIS

 <LinearLayout
android:id="@+id/LinearLayouts02"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:gravity="bottom|end">

<TextView
    android:id="@+id/texts1"
    android:layout_height="match_parent"
    android:layout_width="match_parent"
    android:layout_weight="2"
    android:text="@string/forgotpass"
    android:padding="7dp"
    android:gravity="bottom|center_horizontal"
    android:paddingLeft="10dp"
    android:layout_marginBottom="30dp"
    android:bottomLeftRadius="10dp"
    android:bottomRightRadius="50dp"
    android:fontFamily="sans-serif-condensed"
    android:textColor="@color/colorAccent"
    android:textStyle="bold"
    android:textSize="16sp"
    android:topLeftRadius="10dp"
    android:topRightRadius="10dp"
   />

</LinearLayout>
Right answered 21/3, 2018 at 12:58 Comment(0)
C
0

simply use android:gravity="bottom" in LinearLayout

Clark answered 4/4, 2023 at 2:39 Comment(0)
F
-2

try this

<LinearLayout
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_gravity="bottom"
    android:orientation="vertical" >

    <TextView
        android:id="@+id/textViewProfileName"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="TextView" />

</LinearLayout>
Fallingout answered 27/2, 2014 at 14:30 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.