101

Alright, this specific layout is just annoying me. And can't seem to find a way to have a listView, with a row of buttons at the bottom so that the listview doesn't extend over top of the buttons, and so the buttons are always snapped to the bottom of the screen. Here's what I want:

removed dead ImageShack link

It seems like it should be so easy, but everything I've tried has failed. Any help?

Here's my current code:

    RelativeLayout container = new RelativeLayout(this);
    container.setLayoutParams(new RelativeLayout.LayoutParams(LayoutParams.FILL_PARENT,LayoutParams.FILL_PARENT));

    //** Add LinearLayout with button(s)

    LinearLayout buttons = new LinearLayout(this);

    RelativeLayout.LayoutParams bottomNavParams = new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
    bottomNavParams.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);
    bottomNavParams.addRule(RelativeLayout.CENTER_HORIZONTAL);
    buttons.setLayoutParams(bottomNavParams);


    ImageButton newLayer = new ImageButton(this);
    newLayer.setImageResource(R.drawable.newlayer);
    newLayer.setLayoutParams(new LinearLayout.LayoutParams(45, LayoutParams.FILL_PARENT));
    buttons.addView(newLayer);

    container.addView(buttons);

    //** Add ListView

    layerview = new ListView(this);

    RelativeLayout.LayoutParams listParams = new RelativeLayout.LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT);
    listParams.addRule(RelativeLayout.ABOVE, buttons.getId());

    layerview.setLayoutParams(listParams);

    container.addView(layerview);
SuperBiasedMan
  • 9,814
  • 10
  • 45
  • 73
Kleptine
  • 5,089
  • 16
  • 58
  • 81
  • Good question,lot of dev's are going to get stuck on this. – Signcodeindie Mar 10 '14 at 05:42
  • Thankfully, the designer in Android is actually pretty sweet. Therefore, when creating a layout/UI, try to use the Designer/XML. Especially for this scenario since it's merely a set of buttons and a ListView. – Subby May 06 '14 at 10:33

7 Answers7

137

I think this is what you are looking for.

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

    <Button android:layout_width="fill_parent"
        android:layout_height="wrap_content" android:id="@+id/testbutton"
        android:text="@string/hello" android:layout_alignParentBottom="true" />

    <ListView android:layout_width="fill_parent"
        android:layout_height="fill_parent" android:id="@+id/list"
        android:layout_alignParentTop="true" android:layout_above="@id/testbutton" />

</RelativeLayout>
lars
  • 2,015
  • 1
  • 14
  • 8
  • That's what I've basically been using, though I'm writing the layout in Java. The listView still extends over the buttons. – Kleptine Mar 05 '10 at 01:28
  • 1
    The only thing I'm changing is that I'm adding a relativeLayout around the ListView because I can't call addRule(RelativeLayout.ABOVE) on a ListView. – Kleptine Mar 05 '10 at 01:28
  • 2
    This code should work fine. `android:layout_above="@id/testbutton"` will keep the `ListView` above the `Button`. – CommonsWare Mar 05 '10 at 01:29
  • When i use this I get the list to stop above the button and then start scrolling internally. – lars Mar 05 '10 at 01:31
  • 7
    You don't call `addRule(RelativeLayout.ABOVE)` on a `RelativeLayout`, either. You call it on a `RelativeLayout.LayoutParams`. You then add the `ListView` to the `RelativeLayout`, supplying that `RelativeLayout.LayoutParams`. Please consider switching to XML and inflating it, for long-term maintainability. – CommonsWare Mar 05 '10 at 01:32
  • I edited in my code in my first post. If all else fails I'll try out the XML route. My only problem with XML is it's hard to make things on the fly, which my application does a lot of. – Kleptine Mar 05 '10 at 01:33
  • But you can always create your layouts in xml and get all components in java and set visible on the components that you don't want to have in current layout. – lars Mar 05 '10 at 01:37
  • Alright, the XML worked after inflating it. Point taken. :P God knows why it didn't work in Java. Thanks. – Kleptine Mar 05 '10 at 02:06
  • Heh, I know I'm late, just ran into this problem myself, and this XML helped me as well! Thanks! – Kevin Coppock Aug 11 '10 at 23:26
  • I'd like to add that the in the layout XML file the `ListView` must be placed _after_ the `Button` (like in this example), otherwise Eclipse keeps complaining that it cannot find the resource you're referencing on the `layout_above` attribute. – buc Jan 07 '12 at 15:07
57

I had the same problem for ages.

The solution to keeping the ListView above the buttons, but preventing it from covering them up when the list is long, is to set android:layout_weight="1.0" on the ListView. Leave the layout_weight on the buttons unset so that they remain at their natural size, otherwise the buttons will get scaled. This works with LinearLayout.

There's an example in the Android ApiDemos: ApiDemos/res/layout/linear_layout_9.xml

Thomas
  • 2,751
  • 5
  • 31
  • 52
David Ingram
  • 571
  • 4
  • 2
20

I was just searching for an answer to this question and this was one of the first results. I feel as if all of the answers, including the one that is currently chosen as the "best answer" is not addressing the issue being asked about. The problem that is being stated is that there is an overlap of the two components Button and ListView in that the ListView is taking up the entire screen, and the Button is visually floating above (in front of) the ListView (blocking view/access of the last item in the ListView)

Based on the answers I've seen here and on other forums, I finally came to a conclusion on how to resolve this.

Originally, I had:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
  xmlns:android="http://schemas.android.com/apk/res/android"
  android:orientation="vertical"
  android:layout_width="fill_parent"
  android:layout_height="fill_parent"
  android:background="#FF394952">

  <ListView
    android:id="@+id/game_list"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:layout_alignParentTop="true"
    />

  <LinearLayout
    android:orientation="horizontal"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:layout_alignParentBottom="true"
    style="@android:style/ButtonBar">

    <Button
      android:id="@+id/new_game"
      android:layout_width="fill_parent"
      android:layout_height="wrap_content"
      android:text="@string/new_game"
      android:textColor="#FFFFFFFF"
      android:background="@drawable/button_background" />
  </LinearLayout>

</RelativeLayout>

Note the use of RelativeLayout as the root node.

This is the final, working version in which the Button does not overlap the ListView:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
  xmlns:android="http://schemas.android.com/apk/res/android"
  android:orientation="vertical"
  android:layout_width="fill_parent"
  android:layout_height="fill_parent"
  android:background="#FF394952">

  <ListView
    android:id="@+id/game_list"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:layout_alignParentTop="true"
    android:layout_weight="1.0" />

  <LinearLayout
    android:orientation="horizontal"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:layout_alignParentBottom="true"
    style="@android:style/ButtonBar">

    <Button
      android:id="@+id/new_game"
      android:layout_width="fill_parent"
      android:layout_height="wrap_content"
      android:text="@string/new_game"
      android:textColor="#FFFFFFFF"
      android:background="@drawable/button_background" />
  </LinearLayout>

</LinearLayout>

There are only two differences. First, I've switched to using a LinearLayout. This will help with the next bit, which was adding android:layout_weight to my ListView

I hope this helps.

Dallas
  • 1,045
  • 1
  • 8
  • 25
  • This solves, but who would guess!? When you give `android:layout_alignParentBottom` inside a `LinearLayout` parent, ADT says "Invalid layout param in a LinearLayout: layout_alignParentBottom"! – Aswin Kumar Sep 19 '12 at 20:15
8

The best way is a relative layout that sets the buttons below the listview. In this example the buttons are also in a linear layout because it is easier to put them side by side at an equal size.

<RelativeLayout android:id="@+id/RelativeLayout01" 
android:layout_width="fill_parent" 
android:layout_height="fill_parent">

<ListView android:id="@+id/ListView01" 
android:layout_alignParentTop="true"
android:layout_width="fill_parent" 
android:layout_height="fill_parent">
</ListView>

<LinearLayout android:id="@+id/LinearLayout01" 
android:layout_below="@+id/ListView01" 
android:layout_width="fill_parent" 
android:layout_height="wrap_content" 
android:layout_alignParentBottom="true">
<Button android:id="@+id/ButtonJoin" 
android:text="Join"
android:layout_width="fill_parent" 
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_alignParentBottom="true">
</Button>
<Button android:id="@+id/ButtonJoin" 
android:layout_alignRight="@id/ButtonCancel" 
android:layout_width="fill_parent" 
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="Cancel"
android:layout_alignParentBottom="true">
</Button>
</LinearLayout>

</RelativeLayout>
Patrick Kafka
  • 9,795
  • 3
  • 29
  • 44
  • The problem is that it extends over top of the Buttons at the bottom if the listview is too long, though. I can't figure out how to get it to stop above the buttons. – Kleptine Mar 05 '10 at 01:18
  • 2
    If you are using (I think 1.5, maybe even 1.6) you MUST have the buttons BEFORE the ListView when using RelativeLayout rules - otherwise, the layout is not aware of the Buttons yet because it reads them in order, which is why your ListView extends past them. – Tim H Mar 06 '10 at 01:54
  • This does not work for me. Like Tim H says, for me I must put the ListView after the LinearLayout and then make the ListView layout_above, like repoc's answer above. – Nemi Sep 01 '10 at 16:35
  • this won't work, the button not be on screen, and won't scroll – Vaibhav Mishra Nov 22 '11 at 13:25
1

I know this post is rather old, but, to answer the original poster's question, the reason the code did not work was buttons.getId() returns -1. If you are going to do this, you need to set do something like call buttons.setId(10). If you do that, the code works just fine.

Doo Dah
  • 3,979
  • 13
  • 55
  • 74
0

the easiest solution would be to create two linear layouts, one with the button and the other with the list view(Wrap content on the button height and match parent on the list layout height). then only make a scroll view over the layout with the list view and the button layout will be ignored. hope it helps, sorry i didn't feel like writing out the code.

Pete
  • 11
-1

this should work. to have buttons above the listview too, put the buttons inside another linear layout.

<LinearLayout> main container // vertical

<LinearLayout> scrollview must be contained in a linear layout //vertical - height to fill parent

    <ScrollView> set the height of this to fill parent

        <ListView> will be contained in the scrollview
        </ListView>

    </ScrollView>

</LinearLayout>

<LinearLayout> //horizontal - height to wrap content

<Button>

</Button>

</LinearLayout>

</LinearLayout>
Rhys
  • 219
  • 2
  • 2