user1195883
user1195883

Reputation: 824

Android layout_weight confusion (three elements, one should grow to fill the screen)

I would like to achieve the following layout:

enter image description here

ListView LV1 should wrap its content and stay at the top. LinearLayout LL3 should wrap its content and stay at the bottom. ListView LV2 should fill the remaining screen.

It is working fine as long as LV2 has enough entries to fill the screen. But when LV2 only contains for example two or zero elements, LL3 shifts up.

What do I need to change in order to have LV2 always fill the screen regardless of the number of elements in the ListView and have LL3 stay at the bottom?

Here's my layout:

<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    app:layout_behavior="@string/appbar_scrolling_view_behavior">

    <ListView
        android:id="@+id/LV1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="@dimen/activity_vertical_margin"
        android:layout_weight="0"
        android:drawSelectorOnTop="true"></ListView>

    <ListView
        android:id="@+id/LV2"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_marginTop="@dimen/activity_vertical_margin"
        android:layout_weight="1"></ListView>


    <LinearLayout
        android:id="@+id/LL3"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_weight="0"
        android:orientation="horizontal">

        <Button
            android:id="@+id/button_cancel"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="@string/Button_Cancel"

            />

        <Button
            android:id="@+id/button_save"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="@string/Button_Save"

            />

    </LinearLayout>


</LinearLayout>

Upvotes: 0

Views: 330

Answers (4)

user6266515
user6266515

Reputation: 1

if there are three text fields and two of them declare a weight of 1, while the other is given no weight, the third text field without weight will not grow and will only occupy the area required by its content. The other two will expand equally to fill the space remaining after all three fields are measured. If the third field is then given a weight of 2 (instead of 0), then it is now declared more important than both the others, so it gets half the total remaining space, while the first two share the rest equally.

Upvotes: 0

Amit Vaghela
Amit Vaghela

Reputation: 22955

Use weightSum properly, you will get it

Check this

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:weightSum="11"
    app:layout_behavior="@string/appbar_scrolling_view_behavior">

    <ListView
        android:id="@+id/LV1"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_marginTop="@dimen/activity_vertical_margin"
        android:layout_weight="2"
        android:drawSelectorOnTop="true" />

    <View //this view is added just to separate listiview
        android:id="@+id/view1"
        android:layout_width="match_parent"
        android:layout_height="2dp"
        android:background="#000000" />

    <ListView
        android:id="@+id/LV2"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_marginTop="@dimen/activity_vertical_margin"
        android:layout_weight="8" />

    <View //this view is added just to separate listiview
        android:id="@+id/view2"
        android:layout_width="match_parent"
        android:layout_height="2dp"
        android:background="#000000" />

    <LinearLayout
        android:id="@+id/LL3"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        android:orientation="horizontal">

        <Button
            android:id="@+id/button_cancel"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="@string/Button_Cancel" />

        <Button
            android:id="@+id/button_save"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="@string/Button_Save" />   
    </LinearLayout>

</LinearLayout>

Upvotes: 0

Yasir Tahir
Yasir Tahir

Reputation: 800

Better approach is to use RelativeLayout instead of LinearLayout. But you can also achieve this with LinearLayout. Please see the sample code below:

<?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"
          android:weightSum="1">


<LinearLayout
    android:id="@+id/LL1"
    android:layout_width="match_parent"
    android:layout_height="0dp"
    android:layout_weight="0.1"
    android:background="@android:color/highlighted_text_dark"
    android:orientation="vertical">


</LinearLayout>

<LinearLayout
    android:id="@+id/LL2"
    android:layout_width="match_parent"
    android:layout_height="0dp"
    android:layout_weight="0.8"
    android:background="@android:color/suggestion_highlight_text"
    android:orientation="vertical">


</LinearLayout>

<LinearLayout
    android:id="@+id/LL3"
    android:layout_width="match_parent"
    android:layout_height="0dp"
    android:layout_weight="0.1"
    android:background="@android:color/perms_costs_money"
    android:orientation="vertical">


</LinearLayout>

</LinearLayout>

The output of this code will be:

enter image description here

You can modify the weightSum and the number of childs of Parent LinearLayout as per your requirements.

Upvotes: 0

yennsarah
yennsarah

Reputation: 5517

Since you can't tell your LL3 to fix itself at the bottom, you should change the wrapping LinearLayout to a RelativeLayout:

//pseudo code:
<RelativeLayout>
    <LV1
        android:alignParentTop="true"/>
    <LV2
        android:layout_below="@+id/lv1"
        android:layout_above="@+id/ll3"/>
    <LL3
        android:alignParentBottom="true"/>
</RelativeLayout>

Upvotes: 2

Related Questions