1

I'm trying to create a layout that contains a ListView with a button underneath it, and also make it so that the button 'sticks' to the bottom of the ListView, even when I add or delete a row from the ListView.

With the layout code below, when I add a new row to the list, the button 'moves' to its correct location right beneath the bottom of the ListView. So that works fine.

The problem is when I delete a row from the ListView, the button stays where it is and doesn't 'move up' so that it sticks to the bottom of the ListView. When I rotate the device and it recreates the view, the button does in fact move up, but I'd like it to automatically move up when a row is deleted.

Here is the code I have now:

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

    <ListView
        android:id="@+id/listView"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1.0" />           

    <ImageButton
        android:id="@+id/addButton"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@drawable/add_button" />

</LinearLayout>

SOLUTION:

The solution was to create a small layout file that contains just the button, then add it as the footer of the ListView programatically.

Inside my fragment:

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup parent, Bundle savedInstanceState) 
{ 

    ...

    View footerView = inflater.inflate(R.layout.listview_footer, null, false);

    addButton = (ImageButton) footerView.findViewById(R.id.addButton);

    listView.addFooterView(footerView);

    data = getListViewData();

    adapter = new MyListAdapter(getActivity(), data);

    listView.setAdapter(adapter);

    ...

}

listview_footer.xml:

<?xml version="1.0" encoding="utf-8"?>

<ImageButton
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/addButton"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:src="@drawable/add_button" />

The listview_footer.xml just contains the button, and no layout.

Now, when I delete a row from the ListView, the button moves up to 'stick' to the bottom of the ListView. And as before, when I add a row to the ListView, the button moves down below it.

JDJ
  • 4,298
  • 3
  • 25
  • 44

4 Answers4

1
<RelativeLayout   
    android:layout_width="match_parent"
    android:layout_height="match_parent"
     >                

    <ListView
        android:id="@+id/listView"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
         />           

    <ImageButton
        android:id="@+id/addButton"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below= "@+id/listView"
        android:src="@drawable/add_button" />

</RelativeLayout>
Aniruddha
  • 4,477
  • 2
  • 21
  • 39
1

User RelativeLayout instead. Add android:layout_alignParentBottom="true" to Image Button and android:layout_above="@+id/addButton" to listView

    <RelativeLayout   
        android:layout_width="match_parent"
        android:layout_height="match_parent"
         >                

        <ListView
            android:id="@+id/listView"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
    android:layout_above="@+id/addButton"
 android:layout_alignParentTop="true"/>           

        <ImageButton
            android:id="@+id/addButton"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:src="@drawable/add_button" 
            android:layout_alignParentBottom="true"

    />

    </RelativeLayout>
Sunil Kumar Sahoo
  • 53,011
  • 55
  • 178
  • 243
1

You can add button to the footer of the listview.

View footerView = View.inflate(this, R.layout.footer, null);
listview.addFooterView(footerView);

Make an xml file for the footer view in which you will add a button as per your UI needs.

Footer.xml may look like following:

<?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"
 android:padding="5dip">

 <Button android:id="@+id/previous"
  android:layout_width="wrap_content" android:layout_height="wrap_content"
  android:layout_centerHorizontal="true" />

</RelativeLayout>

This link may be helpful for you.

Community
  • 1
  • 1
Gaurav Gupta
  • 4,586
  • 4
  • 39
  • 72
1

I had a similar situation where I wanted a button to always be in the bottom right of my list, and there would be many deletion/additions to the list. I used a relative Layout:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@color/search_bg" >

    <ListView
        android:id="@+id/list_searchfilters"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
       android:divider="@android:color/transparent"
        android:dividerHeight="10dp"
        android:listSelector="@drawable/search_list_selector" />

    <Button
        android:id="@+id/add_filter_button"
        android:layout_width="40dp"
        android:layout_height="40dp"
        android:layout_marginTop="20dp"
        android:layout_below="@id/list_searchfilters"
        android:layout_alignParentRight="true"
        android:layout_marginRight="15dp" />
</RelativeLayout>

And everytime a row would be deleted or added I would just call LayoutUtils.setListViewHeightBasedOnChildren(mSearchListView); which I had defined as :

public static void setListViewHeightBasedOnChildren(ListView listView) {
            ListAdapter listAdapter = listView.getAdapter(); 
            if (listAdapter == null) {
                // pre-condition
                return;
            }

            int totalHeight = 0;
            for (int i = 0; i < listAdapter.getCount(); i++) {
                View listItem = listAdapter.getView(i, null, listView);
                listItem.measure(0, 0);
                totalHeight += listItem.getMeasuredHeight();
            }

            ViewGroup.LayoutParams params = listView.getLayoutParams();
            params.height = totalHeight + (listView.getDividerHeight() * (listAdapter.getCount() - 1));
            listView.setLayoutParams(params);
            listView.requestLayout();
        }
Kartik_Koro
  • 1,277
  • 1
  • 11
  • 23
  • Thanks for this. This looks like an interesting solution. I will have to try it out. – JDJ Jun 30 '14 at 06:32