Question

I'm trying to construct a layout where there is a text view at the top of the screen and a bottom bar at the bottom of the screen. Each of these views should stay fixed in place and in between the 2 should be a ListView.

TOPBAR
LISTVIEW (scrollable)
BOTTOM BAR

My layout (see below) almost works: the top and bottom components stay fixed and the listview scrolls. The "problem" is that the final row of my ListView remains hidden behind the bottom bar.

Any suggestions on how to adjust the layout?

Thanks!

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        xmlns:android="http://schemas.android.com/apk/res/android">
    <LinearLayout
            android:layout_alignParentTop="true"
            android:layout_width="fill_parent"
            android:layout_height="fill_parent"
            android:orientation="vertical"
            >
        <TextView
                android:background="@drawable/blackgrad"
                android:gravity="center"
                android:id="@+id/title"
                android:layout_height="50dip"
                android:layout_width="fill_parent"
                android:text="blah blah"
                android:textColor="#ffffff"
                android:textSize="18sp"
                />
        <ListView
                android:background="#ffffff"
                android:cacheColorHint="#ffffffff"
                android:id="@android:id/list"
                android:layout_height="fill_parent"
                android:layout_width="fill_parent"
                />
    </LinearLayout>
    <LinearLayout
            android:background="#efefef"
            android:layout_alignParentBottom="true"
            android:layout_centerHorizontal="true"
            android:layout_width="fill_parent"
            android:layout_height="50dip"
            android:orientation="horizontal">
        <Button
                android:layout_height="wrap_content"
                android:id="@+id/back"
                android:text="Back"
                android:layout_width="wrap_content" />

        <Button
                android:layout_height="wrap_content"
                android:id="@+id/home"
                android:text="Home"
                android:layout_width="wrap_content" />

        <Button
                android:layout_height="wrap_content"
                android:id="@+id/next"
                android:text="Next"
                android:layout_width="wrap_content" />


    </LinearLayout>
</RelativeLayout>
Was it helpful?

Solution

Here comes a simple suggestion. Make a new XML and have a go with this.

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical">
    <TextView
        android:text="Header"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"/>
    <ListView
        android:id="@android:id/list"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_weight="1"/>
    <TextView
        android:text="Footer"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content" 
        android:layout_gravity="bottom"/>
</LinearLayout>

OTHER TIPS

The problem with OPs layout is that the first linear layout is set as android:layout_height="fill_parent" which will cause the first linear layout to fill the parent. It doesn't know that you're going to add further views. What you have to do is add views in the order that they know their size. So you know the size of the top par and the bottom bar, you can add those as android:layout_height="wrap_content". Then add the listview since it's size is unknown at compile time.

I accomplished what you're trying to do in a similar way, using IDs and the layout_below/layout_above attributes. The Views are arranged in a different way, but the end result is the same. A ListView between two other LinearLayouts, one on top and one on bottom.

In the ListView you can see I have:

android:layout_above="@+id/event_list_buttons"
android:layout_below="@id/title_container"

Those attributes position the ListView between my top and bottom LinearLayouts.

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

    <LinearLayout style="@style/TitleBar">
        <ImageView style="@style/TitleBarLogo" android:src="@drawable/logo_small_transparent" />

        <View style="@style/TitleBarSpring" />

        <ImageView style="@style/TitleBarSeparator" />
        <ImageButton style="@style/TitleBarAction" android:src="@drawable/ic_title_refresh"
            android:id="@+id/title_refresh_button" android:onClick="onClick" />
        <ProgressBar style="@style/TitleBarProgressIndicator"
            android:id="@+id/title_refresh_progress" android:visibility="gone" />

        <ImageView style="@style/TitleBarSeparator" />
        <ImageButton style="@style/TitleBarAction" android:src="@drawable/ic_title_search" />
    </LinearLayout>

    <ListView android:layout_width="fill_parent"
        android:layout_height="fill_parent" xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/android:list" android:layout_above="@+id/event_list_buttons"
        android:layout_below="@id/title_container" android:fastScrollEnabled="true"
        android:background="@color/white"></ListView>

    <LinearLayout android:layout_width="fill_parent"
        xmlns:android="http://schemas.android.com/apk/res/android" android:id="@id/event_list_buttons"
        android:layout_height="wrap_content" android:layout_alignParentBottom="true"
        android:gravity="center_horizontal">

        <Button android:layout_width="wrap_content"
            android:layout_height="wrap_content" android:id="@+id/events_list_view_organizing_button"
            android:text="Organizing" android:onClick="onClick"></Button>
        <Button android:layout_width="wrap_content"
            android:layout_height="wrap_content" android:id="@+id/events_list_view_attending_button"
            android:text="Attending" android:onClick="onClick"></Button>

    </LinearLayout>
</RelativeLayout>

I had this kind of problem. I used three layouts instead of two, and this kind of solution :

  • the 3 layouts are stored in a RelativeLayout, as in solutions above
  • the layout containing the listview is linked with the "Topbar" (firstLayout) using android:layout_below
  • the third layout becomes the "bottombar" using android:layout_alignParentBottom="true"
  • and the most important thing (your problem) : I add android:layout_marginBottom to the layout containing the listview. I had to make several adjustement to the value before finding the sufficient margin.

    <LinearLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/firstLayout"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:gravity="left"
        android:orientation="horizontal" >
    
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:layout_gravity="center_vertical"
            android:layout_marginTop="10dip"
            android:text="@string/show_history_text" />
    </LinearLayout>
    
    <LinearLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/secondLayout"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@id/firstLayout"
        android:layout_marginBottom="50dip" >
    
        <ListView
            android:id="@+id/ListNotes"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content" />
    </LinearLayout>
    
    <LinearLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/thirdLayout"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:background="@color/LightSteelBlue"
        android:gravity="left"
        android:orientation="horizontal" >
    
        <Button
            android:id="@+id/btnClose"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:layout_gravity="bottom"
            android:gravity="center_vertical|left"
            android:onClick="BtnCloseClick"
            android:text="@string/btn_close_history_text" />
    </LinearLayout>
    

I've found another way to do this with layout_weight's when enclosed in a linear layout. If you set the ListView's weight to something arbitrarily large and the static bottom bar's weight to something very small, the effect works. Both the list view and the bottom bar's height's must be set to "wrap_content" to make everything work together as well.

    <LinearLayout 
android:layout_width="fill_parent" 
android:layout_height="fill_parent"
android:orientation="vertical"
android:color="@color/bg"
xmlns:android="http://schemas.android.com/apk/res/android" >

    <ListView 
        android:id="@android:id/list" 
        android:padding="5dp"
        android:divider="@color/bg"
        android:dividerHeight="4dp"
        android:layout_width="fill_parent" 
        android:layout_height="wrap_content"
        android:layout_weight="20"
        >
    </ListView>

     <TextView android:text="Sorry, no results were found" android:id="@android:id/empty" android:layout_width="fill_parent" android:layout_height="fill_parent"></TextView>


    <include layout="@layout/bottom_bar"  android:layout_weight=".1" android:id="@+id/bottomBar" android:layout_alignParentBottom="true" android:layout_width="fill_parent" android:layout_height="wrap_content"></include>

I've found I think the easier solution just from this post

Just declare both bars BEFORE the viewlist adding android:layout_alignParentBottom="true" and android:layout_alignParentTop="true" in each case.

Then specify in the viewlist layout that it set between them with android:layout_above="id_of_footer" and android:layout_below="id_of_header" properties.

This is working example from my app. Just with footer bar.

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical" >

<LinearLayout
    android:id="@+id/bottom_bar"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:layout_alignParentBottom="true"
    android:background="#333333"
    android:padding="@dimen/padding_small" >

    <Button
        android:id="@+id/bt_add_session"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:onClick="addSession"
        android:text="@string/add_session" />

    <TextView
        android:id="@+id/lb_summary"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:gravity="right"
        android:text="@string/summary_example"
        android:textAppearance="?android:attr/textAppearanceSmall"
        android:textColor="#FFFFFF" />
</LinearLayout>

<ListView
    android:id="@+id/vl_sessions"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:layout_above="@id/bottom_bar" >
</ListView>

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top