1

I've been trying to create a RelativeLayout with a header, body (list) and footer. I want the header to be above everything (aligned to top), the body (list) to be under the header (when scrolling) and the footer (aligned to bottom) to be above the body (list) - only when it's visible.

I've managed to do so PERFECTLY when it comes to how things look but apparently the XML layout is the cause to the issues I've been having when clicking on listItems (see here, and here).

In order to solve the issues, I had to wrap the ListView with LinearLayout and put it between the header and the footer (in the XML). This solves the listItems clicking issues BUT creates a new issue - the footer hides the last ListView item, even though the list does go under the header when scrolling it down.

I'm pretty much desperate here :\

This is the XML which creates the perfect layout but causes the List Item clicking issues:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:orientation="vertical"
    android:background="#ffffff"
    >
    <RelativeLayout
        android:background="@drawable/top_background"
        android:layout_width="fill_parent"
        android:layout_height="50dip"
        android:id="@+id/top_control_bar"
        >
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="fill_parent"
            android:text="Droidmarks"
            android:layout_alignParentLeft="true"
            android:layout_toLeftOf="@+id/add_bookmark"
            android:textSize="20dip"
            android:textColor="#a0cb26"
            android:shadowColor="#7a9b1b"
            android:shadowRadius="5"
            android:layout_marginLeft="5dip"
            android:gravity="left|center" />
        <Button
            android:id="@+id/add_bookmark"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="right|center"
            android:layout_alignParentRight="true"
            android:text="Add"
        />
    </RelativeLayout>
    <LinearLayout
        android:id="@+id/bottom_control_bar"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:background="@drawable/top_background"
        android:visibility="invisible"
        >
        <Button
            android:id="@+id/test"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="right|center"
            android:layout_alignParentRight="true"
            android:text="Add"
        />
    </LinearLayout>

    <ListView
        android:id="@android:id/list"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_below="@id/top_control_bar"
        android:layout_above="@id/bottom_control_bar"
        android:drawSelectorOnTop="false"
        android:focusable="false"
        android:focusableInTouchMode="false"
        android:cacheColorHint="#ffffff"
        android:listSelector="@drawable/selected_item"
        />
    <TextView android:id="@android:id/empty" android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="No Bookmarks found. You can add one by clicking the star."
        android:layout_below="@id/top_control_bar" android:layout_above="@id/bottom_control_bar" />
</RelativeLayout>

This is the XML which hide the last List Item but solves the clicking issues:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:orientation="vertical"
    android:background="#ffffff"
    >
    <RelativeLayout
        android:background="@drawable/top_background"
        android:layout_width="fill_parent"
        android:layout_height="50dip"
        android:id="@+id/top_control_bar"
        android:layout_alignParentTop="true"
        >
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="fill_parent"
            android:text="Droidmarks"
            android:layout_alignParentLeft="true"
            android:layout_toLeftOf="@+id/add_bookmark"
            android:textSize="20dip"
            android:textColor="#a0cb26"
            android:shadowColor="#7a9b1b"
            android:shadowRadius="5"
            android:layout_marginLeft="5dip"
            android:gravity="left|center" />
        <Button
            android:id="@+id/add_bookmark"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="right|center"
            android:layout_alignParentRight="true"
            android:text="Add"
        />
    </RelativeLayout>

    <LinearLayout
        android:id="@+id/listArea"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        android:layout_below="@id/top_control_bar"
        >
        <ListView
            android:id="@android:id/list"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:drawSelectorOnTop="false"
            android:cacheColorHint="#ffffff" />
        <TextView android:id="@android:id/empty" android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="No Bookmarks found. You can add one by clicking the star." />
    </LinearLayout>

    <LinearLayout
        android:id="@+id/bottom_control_bar"
        android:layout_above="@id/listArea"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:background="@drawable/top_background"
        android:orientation="horizontal"
        android:visibility="visible"
        >
        <Button
        android:id="@+id/test"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="right|center"
        android:layout_alignParentRight="true"
        android:text="Add"
    />
    </LinearLayout>
</RelativeLayout>

I'd appreciate any help to somehow find a solution for both issues!

Thank you!

Community
  • 1
  • 1
Lior Iluz
  • 26,213
  • 16
  • 65
  • 114

1 Answers1

3

Can I ask why you're using a RelativeLayout at all for the container? It seems like a perfect place to just use a LinearLayout with a weighted center area (the listview) that's set up to take all remaining area after the wrap_height-set header and footer. RelativeLayouts are great for simplifying deeply nested layouts which contain both horizontal and vertical elements, but your outer layer here only contains 3 vertical elements anyways, so go with a LinearLayout with orientation:vertical unless I'm missing something here.

EDIT: In short, try this; this should give you a fixed height header, a wrapping-height footer, and the center area taking up all remaining space. Make sure the outer layout is set to fill_parent height and the middle area is set to a fixed height but with a layout_weight="1". I like to use "0px" for the base layout_height when I'm using layout_weight just to keep it clear to me when I go back and reread it later.

<?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"
    android:background="#ffffff"
    >
    <RelativeLayout
        android:background="@drawable/top_background"
        android:layout_width="fill_parent"
        android:layout_height="50dip"
        android:id="@+id/top_control_bar"
        > <!-- snip - inner contents unchanged -->
    </RelativeLayout>

    <LinearLayout
        android:id="@+id/listArea"
        android:layout_width="fill_parent"
        android:layout_height="0px"
        android:layout_weight="1"
        android:orientation="horizontal"
        ><!-- snip - inner contents unchanged -->
    </LinearLayout>

    <LinearLayout
        android:id="@+id/bottom_control_bar"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:background="@drawable/top_background"
        android:orientation="horizontal"
        android:visibility="visible"
        ><!-- snip - inner contents unchanged -->
    </LinearLayout>
</LinearLayout>
Yoni Samlan
  • 37,905
  • 5
  • 60
  • 62
  • Hi Yoni! Thank you for your response! Tried what you said and now I lost the bottom_control_bar, even though I added it android:layout_above... Can you please update your answer with the modifications you mean? – Lior Iluz Oct 31 '10 at 22:17
  • btw, I'm using RelativeLayout as a wrapper because that's the only way I can position the inner elements relative to each other. – Lior Iluz Oct 31 '10 at 22:27
  • Not sure I understand what you mean by "the only way I can position the inner elements relative to each other" -- if a Layout is inside another Layout, the wrapper type of the outer parent has no effect on the inner layout's *children*, just on the layout itself. Your outer RelativeLayout here has 3 children; to make it Linear, set the first one's height to wrap_content, the 3rd one's to wrap_content, and the middle one to height of 0px with a layout_weight of "1". The direct children of a LinearLayout ignore RelativeLayout flags like android:layout_above and so on. – Yoni Samlan Nov 01 '10 at 14:09
  • Yoni, Can't get it to work... Tried what you said, a mix of things... all I get is disappearing layouts :\ Any chance you use my code and update your answer with what you suggested? – Lior Iluz Nov 01 '10 at 19:45
  • btw, Tried what you said according to the following guide by Romain Guy: http://android-developers.blogspot.com/2009/02/android-layout-tricks-1.html . – Lior Iluz Nov 01 '10 at 20:03