Android Layout with ListView between a "top bar" and "bottom bar"
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:layo开发者_C百科ut_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>
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>
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 View
s are arranged in a different way, but the end result is the same. A ListView
between two other LinearLayout
s, 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 LinearLayout
s.
<?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>
精彩评论