Raptor Raptor - 1 year ago 110
Android Question

How to force a Linear layout to the bottom of the screen while it's inside a ScrollView?

I found a little difficult to force layout (that is inside a SrollView) to be on the bottom of the screen.

Well, it would be easy if I detached this Bottom layout off the ScrollView and create it's own layout on the very bottom using Gravity, but
when someone expands some of the layouts (or rotate to landscape) the app is going to start using the ScrollView. At this moment I want the bottom
part to roll up and down with all the stuff and my "Stretching layout" should be only about 8dp (similar to upper dark-blue line) this time.

enter image description here

Here is my structure: (it is not so complicated how it might seems to be) :)

<ScrollView
android:id="@+id/lt_bcnbldmenu_scroll"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_alignParentBottom="true"
android:layout_below="@+id/lt_FillScrl"
android:scrollbars="vertical" >

<LinearLayout //HELPER LAYOUT
android:id="@+id/lt_ScrollingPart"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_gravity="top"
android:gravity="bottom"
android:orientation="vertical" >

<LinearLayout //only to make some space (upper dark-blue line)
android:id="@+id/lt_Fill1"
android:layout_width="fill_parent"
android:layout_height="6dp"
android:background="#70000000"
android:orientation="vertical" >
</LinearLayout>

<LinearLayout //blue background layout
android:id="@+id/lt_bgLine"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_alignParentLeft="true"
android:layout_alignParentRight="true"
android:layout_below="@+id/lt_Fill1"
android:background="@drawable/bg_line"
android:orientation="vertical" >

<LinearLayout //MENU LAYOUT
android:id="@+id/lt_Menu"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
android:layout_marginLeft="16dp"
android:layout_marginRight="16dp"
android:layout_marginTop="8dp"
android:background="@drawable/bg_main"
android:orientation="vertical" >

<LinearLayout //Stuff (first layout)
android:id="@+id/lt_pic"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:gravity="top|fill_horizontal"
android:orientation="horizontal" >

<ImageButton
android:id="@+id/img_bcnbldmenu_pic"
android:layout_width="100dp"
android:layout_height="100dp"
android:background="@drawable/bg_main_rd"
android:padding="16dp"
android:scaleType="fitXY"
android:src="@drawable/lighthouse" />

<EditText
android:id="@+id/edt_bcnbldmenu_adress"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_gravity="right"
android:layout_weight="1"
android:background="@drawable/bg_main_d"
android:ems="10"
android:gravity="start"
android:hint="Beacon Adress..."
android:inputType="textMultiLine"
android:padding="16dp"
android:textColor="#222222"
android:textColorHint="#777777"
android:textSize="14sp" />

</LinearLayout>

<LinearLayout //Stuff (second layout)
android:id="@+id/lt_group"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="@drawable/bg_main_ud"
android:orientation="horizontal" >

<EditText
android:id="@+id/edt_bcnbldmenu_group"
android:layout_width="fill_parent"
android:layout_height="100dp"
android:layout_centerHorizontal="true"
android:layout_gravity="left"
android:layout_weight="1"
android:background="#00000000"
android:ems="10"
android:gravity="center"
android:hint="Group..."
android:inputType="textPersonName"
android:minHeight="100dp"
android:textColor="#222222"
android:textColorHint="#777777" />

<Button
android:id="@+id/btn_bcnbldmenu_list"
android:layout_width="68dp"
android:layout_height="fill_parent"
android:layout_gravity="bottom|right"
android:layout_margin="16dp"
android:background="@drawable/btn_list"
android:gravity="center_vertical|center_horizontal"
android:textOff="@string/nothing"
android:textOn="@string/nothing" />

</LinearLayout>

<EditText //Stuff (third layout - actually only a textbox)
android:id="@+id/edt_BcnBldMenu_Description"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="#00000000"
android:ems="10"
android:gravity="top|left"
android:hint="Description..."
android:inputType="textMultiLine"
android:minHeight="100dp"
android:padding="16dp"
android:textColor="#222222"
android:textColorHint="#777777"
android:textSize="16sp" />

</LinearLayout>

</LinearLayout>

<LinearLayout //STRETCHING LAYOUT (lower dark-blue line)
android:id="@+id/lt_Fill2"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="#70000000"
android:minHeight="32dp"
android:orientation="vertical" >
</LinearLayout>

<LinearLayout //BOTTOM LAYOUT
android:id="@+id/lt_BottomMenu"
android:layout_width="fill_parent"
android:layout_height="62dp"
android:layout_weight="1"
android:background="@drawable/bg_line"
android:gravity="bottom"
android:orientation="horizontal" >

<ImageButton
android:id="@+id/imageButton1"
android:layout_width="100dp"
android:layout_height="fill_parent"
android:layout_gravity="left"
android:layout_weight="0"
android:background="#00000000"
android:scaleType="center"
android:src="@drawable/uncheck_press" />

<ImageView //empty image to make some space here
android:id="@+id/imageView1"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:layout_gravity="center_horizontal"
android:layout_weight="1"
android:src="#00000000" />

<ImageButton
android:id="@+id/imageButton2"
android:layout_width="100dp"
android:layout_height="fill_parent"
android:layout_gravity="right"
android:layout_weight="0"
android:background="#00000000"
android:scaleType="center"
android:src="@drawable/crane" />
</LinearLayout>

</LinearLayout>
</ScrollView>


I hope there is an easy way to figure this out, because otherwise I will have to do it programmatically somehow which I really want to avoid.

Thanks in advance! I am looking for a solution for several hours.

Answer Source

The easiest way in my opinion of solving your problem is to check if the helper Linearlayout has less height than the ScrollView.

Also note that the preferred xml syntax is "match_parent" and not "fill_parent", which is technically deprecated.

1. In the XML change layout_height to wrap_content for the helper Linearlayout, also remove layout_gravity and gravity, useless code for this solution. You also add an empty view into the helper LinearLayout. Your XML should look like this:

<ScrollView
    android:id="@+id/lt_bcnbldmenu_scroll"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:layout_alignParentBottom="true"
    android:layout_below="@+id/lt_FillScrl"
    android:scrollbars="vertical" >

    <LinearLayout //HELPER LAYOUT
        android:id="@+id/lt_ScrollingPart"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical" >

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

    <LinearLayout //only to make some space (upper dark-blue line)
        android:id="@+id/lt_Fill1"
        android:layout_width="fill_parent"
        android:layout_height="6dp"
        android:background="#70000000"
        android:orientation="vertical" >
    </LinearLayout>
....

2. in the OnCreate(...) method of the respective Activity, add the following:

final ScrollView scrollView = (ScrollView)findViewById(R.id.lt_bcnbldmenu_scroll);
final LinearLayout helperLayout = (LinearLayout)findViewById(R.id.lt_ScrollingPart);
final View emptyView = findViewById(R.id.lt_empty);

// when post(...) is called all View heights have been measured by Android
helperLayout.post(new Runnable() {
    @Override
    public void run() {
        int nHeightDiff = scrollView.getHeight() - helperLayout.getHeight();
        // Does the ScrollView have more height than what it contains?
        if (nHeightDiff > 0) {
            // add padding to compensate for the missing height, you can also set the height directly via LinearLayout.LayoutParams(...)
            emptyView.setPadding(0, nHeightDiff, 0, 0);
        }
    }
});
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download