1

How to place Button below ListView to follow the next conditions:

  • Button should fill all available space below ListView
  • if ListView content is too big Button should appear at the bottom below ListVew and ListView should be scrolled

enter image description here

pvllnspk
  • 5,667
  • 12
  • 59
  • 97
  • can you post some image how it's look like or post your code whatever you have try. – Haresh Chhelana Oct 10 '14 at 08:31
  • Just added some illustration. – pvllnspk Oct 10 '14 at 08:38
  • 1
    I think you can't do this with easy way. Because ListView height != ListView content height. So ListView couldn't have wrap_content height (it will be always 0 in this case). So if you want to do smth like this, you need to add a lot of code which will calculate content height if listView before drawing and change heights programmatically. – Alexander Mikhaylov Oct 10 '14 at 08:43
  • any proposals will be appreciated, thanks. – pvllnspk Oct 10 '14 at 08:43

1 Answers1

1

I agree that it seems impossible to do such a layout using xml layouts.
You can try to do this dynamically.

Just like a proof-of-concept. Create test application with theme:
<style name="AppTheme" parent="android:Theme.Holo.Light.NoActionBar.Fullscreen">

Create activity layout activity_main.xml like this:

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

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

    <Button
        android:id="@+id/button"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_alignParentBottom="true"
        android:text="Button"/>

</RelativeLayout>

And in the Activity do the thing:

public class MainActivity extends Activity {

    private Button mButton;
    private ListView mListView;

    private static final int BUTTON_MIN_HEIGHT = 300;

    private ArrayAdapter<String> mAdapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        final List<String> values = new ArrayList<String>();
        mAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, android.R.id.text1, values);

        mListView = (ListView) findViewById(R.id.listView);
        mListView.setAdapter(mAdapter);

        mButton = (Button) findViewById(R.id.button);
        mButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                values.add("Something");

                invalidateViews();
            }
        });


    }

    private int getScreenHeight() {
        Display display = getWindowManager().getDefaultDisplay();
        Point size = new Point();
        display.getSize(size);
        return size.y;
    }

    private int getListViewHeight() {
        int listviewElementsHeight = 0;
        for (int i = 0; i < mAdapter.getCount(); i++) {
            View mView = mAdapter.getView(i, null, mListView);
            mView.measure(
                    View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED),
                    View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED));
            listviewElementsHeight += mView.getMeasuredHeight();
        }
        return listviewElementsHeight;
    }

    private void invalidateViews() {
        mAdapter.notifyDataSetChanged();

        int buttonHeight = getScreenHeight() - getListViewHeight();
        Log.e(MainActivity.class.getSimpleName(), "Button height: " + buttonHeight);
        if (buttonHeight < BUTTON_MIN_HEIGHT) {
            buttonHeight = BUTTON_MIN_HEIGHT;
        }
        RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams) mButton.getLayoutParams();
        layoutParams.height = buttonHeight;
        mButton.setLayoutParams(layoutParams);
    }
}

In this example at start we have fullscreen button and an empty list view. On button click one more item will be added to list view and button size will be recalculated and applied correct value. There are methods getScreenHeight() and getListViewHeight() which help us to calculate desired button height. We provide BUTTON_MIN_HEIGHT constant to define minimum height for button. Button height we calculate simply by subtracting listview's height from screen's height.

This example is horrible and not optimised. Problems:

  • calculating list view's height is very long. If you know exact height of list view element and know that list view contains items with only this height, you can calculate item's height one time and then calculate list view's height by multiplying item's height by items count.
  • basically you need to subtract also StatusBar height, and ActionBar height, if you have them (for simplicity in this example I used NoActionBar.Fullscreen theme)
  • you need to define min button height in dimens.xml file and load its value onCreate. In this example I use constant value for simplicity.

As you can see, not a very good solution, but I hope it helps.

References:
How to get listview height in android?
Get screen dimensions in pixels
How to resize a custom view programmatically?

Community
  • 1
  • 1
krossovochkin
  • 12,030
  • 7
  • 31
  • 54