pvllnspk
pvllnspk

Reputation: 5777

Place Button below ListView to fill all available space but Button should have min Height

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

enter image description here

Upvotes: 1

Views: 251

Answers (1)

krossovochkin
krossovochkin

Reputation: 12132

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?

Upvotes: 1

Related Questions