How do I align views at the bottom of the screen?
Asked Answered
G

18

673

Here's my layout code;

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent">

    <TextView android:text="@string/welcome"
        android:id="@+id/TextView"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content">
    </TextView>

    <LinearLayout android:id="@+id/LinearLayout"
        android:orientation="horizontal"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:gravity="bottom">

            <EditText android:id="@+id/EditText"
                android:layout_width="fill_parent"
                android:layout_height="wrap_content">
            </EditText>

            <Button android:text="@string/label_submit_button"
                android:id="@+id/Button"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content">
            </Button>

    </LinearLayout>

</LinearLayout>

What this looks like is on the left and what I want it to look like is on the right.

Android Layout - Actual (Left) and Desired (Right)

The obvious answer is to set the TextView to fill_parent on height, but this causes no room to be left for the button or entry field.

Essentially the issue is that I want the submit button and the text entry to be a fixed height at the bottom and the text view to fill the rest of the space. Similarly, in the horizontal linear layout I want the submit button to wrap its content and for the text entry to fill the rest of the space.

If the first item in a linear layout is told to fill_parent it does exactly that, leaving no room for other items. How do I get an item which is first in a linear layout to fill all space apart from the minimum required by the rest of the items in the layout?


Relative layouts were indeed the answer:

    <?xml version="1.0" encoding="utf-8"?>
    <RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent">

    <TextView
        android:text="@string/welcome"
        android:id="@+id/TextView"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentTop="true">
    </TextView>

    <RelativeLayout
        android:id="@+id/InnerRelativeLayout"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true" >

        <Button
            android:text="@string/label_submit_button"
            android:id="@+id/Button"
            android:layout_alignParentRight="true"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content">
        </Button>

        <EditText
            android:id="@+id/EditText"
            android:layout_width="fill_parent"
            android:layout_toLeftOf="@id/Button"
            android:layout_height="wrap_content">
        </EditText>

    </RelativeLayout>

</RelativeLayout>
Guizot answered 5/3, 2010 at 13:4 Comment(2)
@oneself Paint ;) I'm using a skin on the emulator though courtesy of Tea Vui Huang teavuihuang.com/androidGuizot
+1 for posting the layout XML that solved it. Helped me figure out what was wrong with mine.Atrioventricular
C
547

The modern way to do this is to have a ConstraintLayout and constrain the bottom of the view to the bottom of the ConstraintLayout with app:layout_constraintBottom_toBottomOf="parent"

The example below creates a FloatingActionButton that will be aligned to the end and the bottom of the screen.

<android.support.constraint.ConstraintLayout
   xmlns:android="http://schemas.android.com/apk/res/android"
   xmlns:app="http://schemas.android.com/apk/res-auto"
   xmlns:tools="http://schemas.android.com/tools"
   android:layout_height="match_parent"
   android:layout_width="match_parent">

<android.support.design.widget.FloatingActionButton
    android:layout_height="wrap_content"
    android:layout_width="wrap_content"

    app:layout_constraintBottom_toBottomOf="parent"

    app:layout_constraintEnd_toEndOf="parent" />

</android.support.constraint.ConstraintLayout>

For reference, I will keep my old answer.

Before the introduction of ConstraintLayout the answer was a relative layout.


If you have a relative layout that fills the whole screen you should be able to use android:layout_alignParentBottom to move the button to the bottom of the screen.

If your views at the bottom are not shown in a relative layout then maybe the layout above it takes all the space. In this case you can put the view, that should be at the bottom, first in your layout file and position the rest of the layout above the views with android:layout_above. This enables the bottom view to take as much space as it needs, and the rest of the layout can fill all the rest of the screen.

Crowson answered 5/3, 2010 at 13:14 Comment(8)
FYI: that wouldn't work inside a ScrollView. This is the issue I am facing now. See #3126847Eliezer
That is correct ScrollViews and Relative Layouts do not mix very well. If you have to much content to display everything on one page just use a linearlayout and put in the bottom view last. If you want the view to appear last in the scrollview on small screens and at the bottom of the page on bigger phones consider using different layout files and uses ressource qualifiers to let the device choose the correct layout file.Crowson
ok.. what's the point of the second paragraph of the answer here? "You should find a layout which covers the bottom of the screen first"? then we should use layout_alignParentBottom inside the layout? What do we need android:layout_above for?Adige
You need the above if you want to something like a bar at the bottom and then a LinearLayout above this bar that stretches from the top of the screen to the bar.Crowson
I have read in one of "Android Weekly" that RelativeLayout is memory consuming and should be avoided whenever it is possible.Versed
Relative layout is the best option for such scenarioThine
That properties about botton aligment are not available for my solution: No resource identifier found for attribute 'layout_constraintBottom_toBottomOf' in package 'com.XXX' XXX C:\projects\erp\XXX\Resources\layout\layout_test.axmlDefault
Tried this and it killed the designerPostprandial
R
164

In a ScrollView this doesn't work, as the RelativeLayout would then overlap whatever is in the ScrollView at the bottom of the page.

I fixed it using a dynamically stretching FrameLayout :

<ScrollView 
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_height="match_parent" 
    android:layout_width="match_parent"
    android:fillViewport="true">
    <LinearLayout 
        android:id="@+id/LinearLayout01"
        android:layout_width="match_parent" 
        android:layout_height="match_parent"
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:orientation="vertical">

                <!-- content goes here -->

                <!-- stretching frame layout, using layout_weight -->
        <FrameLayout
            android:layout_width="match_parent" 
            android:layout_height="0dp"
            android:layout_weight="1">
        </FrameLayout>

                <!-- content fixated to the bottom of the screen -->
        <LinearLayout 
            android:layout_width="match_parent" 
            android:layout_height="wrap_content"
            android:orientation="horizontal">
                                   <!-- your bottom content -->
        </LinearLayout>
    </LinearLayout>
</ScrollView>
Receiptor answered 4/11, 2010 at 16:50 Comment(4)
this is great - also, it's "minimal invasive", and more intuitive than the RelativeLayout approach. I'd give more than one upvote if I could!Eris
I use your solution in my application, but in my case I want that when keyboard appears, the buttons stay at the bottom of the screen (behind the keyboard) There is a sulution for that ? Thaks.Unrounded
@DoubleYo: in the manifest android:windowSoftInputMode="adjustPan"Appoggiatura
IF you want the bottom to be fixed permanently so that is shows all the time this does not work. Otherwise it works.Mishamishaan
F
75

You can keep your initial linear layout by nesting the relative layout within the linear layout:

<LinearLayout
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent">

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

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">
        <Button android:text="submit" 
            android:id="@+id/Button" 
            android:layout_width="wrap_content" 
            android:layout_height="wrap_content"
            android:layout_alignParentBottom="true"
            android:layout_alignParentRight="true">
        </Button>
        <EditText android:id="@+id/EditText" 
            android:layout_width="match_parent" 
            android:layout_height="wrap_content"
            android:layout_toLeftOf="@id/Button"
            android:layout_alignParentBottom="true">
        </EditText>
    </RelativeLayout>
</LinearLayout>
Foretop answered 24/4, 2011 at 0:53 Comment(1)
This is a messy approach in that it's not very modular. You shouldn't have overlapping layouts. This design won't work as soon as you want to change the background of the RelativeLayout or want to make any of the views bigger or add views.Councilman
S
46

The answer above (by Janusz) is quite correct, but I personnally don't feel 100% confortable with RelativeLayouts, so I prefer to introduce a 'filler', empty TextView, like this:

<!-- filler -->
<TextView android:layout_height="0dip" 
          android:layout_width="fill_parent"
          android:layout_weight="1" />

before the element that should be at the bottom of the screen.

Sale answered 17/4, 2011 at 15:39 Comment(4)
Is this gonna expand to x or y axis. Giving 0dip for height will make the textview without any height ? or will expand as much as it can just like to x axis ?Row
This expands vertically because the height (vertical axis) is set to 0 and the weight to 1 (assuming that other elements have a zero weight).Sale
On the x axis, it will be as its parent (fill_parent)Sale
Rather than a textview I would use another linear layout. Layout view seems to imply it can be used to fill space?Gaul
P
41

You can do this with a LinearLayout or a ScrollView, too. Sometimes it is easier to implement than a RelativeLayout. The only thing you need to do is to add the following view before the Views you want to align to the bottom of the screen:

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

This creates an empty view, filling the empty space and pushing the next views to the bottom of the screen.

Proboscidean answered 10/3, 2013 at 0:30 Comment(2)
this concept is similar to the filler as @Sale said earlier.Araminta
That's it what I am looking for since hours. Thanks!Ember
M
34

1. Use ConstraintLayout in your root Layout

And set app:layout_constraintBottom_toBottomOf="parent" to let the Layout on the bottom of the screen:

<LinearLayout
    android:id="@+id/LinearLayout"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal"
    app:layout_constraintBottom_toBottomOf="parent">
</LinearLayout>

2. Use FrameLayout in your root Layout

Just set android:layout_gravity="bottom" in your layout

<LinearLayout
    android:id="@+id/LinearLayout"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_gravity="bottom"
    android:orientation="horizontal">
</LinearLayout>

3. Use LinearLayout in your root Layout (android:orientation="vertical")

(1) Set a layout android:layout_weight="1" on the top of the your Layout

<TextView
    android:id="@+id/TextView"
    android:layout_width="match_parent"
    android:layout_height="0dp"
    android:layout_weight="1"
    android:text="welcome" />

(2) Set the child LinearLayout for android:layout_width="match_parent" android:layout_height="match_parent" android:gravity="bottom"

The main attribute is ndroid:gravity="bottom", let the child View on the bottom of Layout.

<LinearLayout
    android:id="@+id/LinearLayout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="bottom"
    android:orientation="horizontal">
</LinearLayout>

4. Use RelativeLayout in the root Layout

And set android:layout_alignParentBottom="true" to let the Layout on the bottom of the screen

<LinearLayout
    android:id="@+id/LinearLayout"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_alignParentBottom="true"
    android:orientation="horizontal">
</LinearLayout>

Output

Enter image description here

Manwell answered 16/10, 2017 at 15:17 Comment(0)
C
29

This also works.

<LinearLayout 
    android:id="@+id/linearLayout4"
    android:layout_width="wrap_content"
    android:layout_height="fill_parent"
    android:layout_below="@+id/linearLayout3"
    android:layout_centerHorizontal="true"
    android:orientation="horizontal" 
    android:gravity="bottom"
    android:layout_alignParentBottom="true"
    android:layout_marginTop="20dp"
>

    <Button
        android:id="@+id/button1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Button" 

    />

    <Button
        android:id="@+id/button2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Button" 


    />

</LinearLayout>

gravity="bottom" to float LinearLayout elements to bottom

Collateral answered 28/12, 2011 at 14:3 Comment(2)
android:layout_alignParentBottom="true" has no effect unless the LinearLayout is nested inside a RelativeLayout.Briefing
An explanation would be in order (e.g. the essential change, how it works, why it works, etc.).Flodden
E
24

Following up on Timores's elegant solution, I have found that the following creates a vertical fill in a vertical LinearLayout and a horizontal fill in a horizontal LinearLayout:

<Space
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_weight="1" />
Elnaelnar answered 15/11, 2015 at 21:51 Comment(3)
@sepehr There must be another factor at play in the case you found where my solution doesn't work. I just tried my solution in a fragment layout, and it works there as well.Elnaelnar
weights are supported in linear layouts and @sepehr they will work in fragments, activities, notifications, dialogs as well ;)Eastsoutheast
This works! What a simple solution.Transcend
R
20

You don't even need to nest the second relative layout inside the first one. Simply use the android:layout_alignParentBottom="true" in the Button and EditText.

Rheo answered 5/3, 2010 at 15:5 Comment(1)
Just a note that although this works with the Button and EditText, if you tried to align a TableLayout this way it would not work. You would have to nest it inside of another RelativeLayout.Axilla
C
12

If you don't wish to make many changes, then you could just put:

android:layout_weight="1"

for the TextView having ID as @+id/TextView i.e

<TextView android:text="@string/welcome" 
    android:id="@+id/TextView" 
    android:layout_width="fill_parent" 
    android:layout_height="wrap_content"
    android:layout_weight="1">
</TextView>
Cushy answered 23/9, 2011 at 12:16 Comment(1)
Or add a surrounding LinearLayout with android:layout_weight="1" - this also works well inside a ScrollView!Savate
D
11

Creating both header and footer, here is an example:

Layout XML

<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:background="@color/backgroundcolor"
    tools:context=".MainActivity">

    <RelativeLayout
        android:layout_width="fill_parent"
        android:layout_height="40dp"
        android:background="#FF0000">
    </RelativeLayout>

    <RelativeLayout
        android:layout_width="fill_parent"
        android:layout_height="40dp"
        android:layout_alignParentBottom="true"
        android:background="#FFFF00">
    </RelativeLayout>

</RelativeLayout>

Screenshot

Enter image description here

Dogoodism answered 10/5, 2015 at 2:25 Comment(0)
P
6

For a case like this, always use RelativeLayouts. A LinearLayout is not intended for such a usage.

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/db1_root"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">

        <!-- Place your layout here -->

    </LinearLayout>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:layout_gravity="bottom"
        android:orientation="horizontal"
        android:paddingLeft="20dp"
        android:paddingRight="20dp" >

        <Button
            android:id="@+id/setup_macroSavebtn"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="Save" />

        <Button
            android:id="@+id/setup_macroCancelbtn"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="Cancel" />

        </LinearLayout>

</RelativeLayout>
Prelect answered 20/5, 2015 at 4:28 Comment(0)
C
5

Use the below code. Align the button to buttom. It's working.

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <Button
        android:id="@+id/btn_back"
        android:layout_width="100dp"
        android:layout_height="80dp"
        android:text="Back" />

    <TextView
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="0.97"
        android:gravity="center"
        android:text="Payment Page" />

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content" >

        <EditText
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_weight="1"/>

        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Submit"/>
    </LinearLayout>

</LinearLayout>
Courtesy answered 17/12, 2013 at 7:33 Comment(0)
E
4

Use android:layout_alignParentBottom="true" in your <RelativeLayout>.

This will definitely help.

Emprise answered 4/7, 2013 at 12:50 Comment(1)
That presumes the user wants to use a RelativeLayout.Eliezer
U
3

This can be done with a linear layout too.

Just provide Height = 0dp and weight = 1 to the layout above and the one you want in the bottom. Just write height = wrap content and no weight.

It provides wrap content for the layout (the one that contains your edit text and button) and then the one that has weight occupies the rest of the layout.

I discovered this by accident.

Underprop answered 5/9, 2013 at 8:22 Comment(0)
A
3

In case you have a hierarchy like this:

<ScrollView> 
  |-- <RelativeLayout> 
    |-- <LinearLayout>

First, apply android:fillViewport="true" to the ScrollView and then apply android:layout_alignParentBottom="true" to the LinearLayout.

This worked for me perfectly.

<ScrollView
    android:layout_height="match_parent"
    android:layout_width="match_parent"
    android:scrollbars="none"
    android:fillViewport="true">
    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
        <LinearLayout
            android:orientation="horizontal"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:gravity="center"
            android:id="@+id/linearLayoutHorizontal"
            android:layout_alignParentBottom="true">
        </LinearLayout>
    </RelativeLayout>
</ScrollView>
Arrange answered 15/4, 2015 at 8:32 Comment(0)
E
3

You can just give your top child view (the TextView @+id/TextView) an attribute: android:layout_weight="1".

This will force all other elements below it to the bottom.

Eliezer answered 17/2, 2016 at 22:19 Comment(0)
P
1

I used the solution Janusz posted, but I added padding to the last View since the top part of my layout was a ScrollView.

The ScrollView will be partly hidden as it grows with content. Using android:paddingBottom on the last View helps show all the content in the ScrollView.

Poriferous answered 22/3, 2012 at 7:45 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.