Shawn Lauzon Shawn Lauzon - 1 month ago 9
Android Question

Using layout_gravity="bottom" to place at bottom of LinearLayout

I would like to place a layout on the bottom of a LinearLayout, but I can't seem to get it to work. I know that I can use RelativeLayout to do this, but I should be able to use LinearLayout, shouldn't I?

EDIT: Actually this is more confusing than I thought. The layout below is simplified. In reality, I'm using fragments on a pre-3.0 device, with the compatibility layer.

I used Hierarchy Viewer to examine what's going on, and found that an android.support.v4.app.NoSaveStateFrameLayout was added to my layout, and that layout has layout_height set to wrap_content. That seems to be what's causing my problem, but I haven't yet figured out how to fix it.

Specifically, why doesn't this work? Shouldn't the layout_gravity place it at the bottom?

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

... stuff here ...

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

... more stuff here ...

</LinearLayout>
</LinearLayout>


BTW, changing layout_height to fill_parent or setting layout_weight don't seem to work either. I just want to better understand what is going on, because clearly I'm missing something important. Thanks.

Answer

So I resolved the problem. It's a two-part solution:

First, the way to do this without using LinearLayout is to provide weight to the element above so that it takes up all of the empty space. BTW, you can see this example in the API demos: http://developer.android.com/resources/samples/ApiDemos/res/layout/linear_layout_3.html

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

        ... stuff here ...
        <TextView
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:weight="1"/>
        <LinearLayout 
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:orientation="horizontal">

            ... more stuff here ...

     </LinearLayout>
</LinearLayout>

This by itself didn't solve my problem, as I had a NoSaveStateFrameLayout with layout_width="wrap_content" as a parent view, and so I needed to get that fixed first. I'm using code based on the wonderful Google I/O App, and when I searched the code for NoSaveStateFrameLayout, I found this:

// For some reason, if we omit this, NoSaveStateFrameLayout thinks we are
// FILL_PARENT / WRAP_CONTENT, making the progress bar stick to the top of the activity.
mRootView.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.FILL_PARENT,
        ViewGroup.LayoutParams.FILL_PARENT));

Thanks for an awesome comment Google!!! I added this into my source and everything worked great!

The moral of the story: Hierarchy Viewer and comments are your friends.