How can I limit the height of a ListView in a GridLayout?
I have GridLayout
one containing a ListView
and a TextView
. When items are added to ListView
it it will grow in size and push it TextView
below it out of the screen. I thought that by setting layout_gravity="fill"
in the ListView it would not grow at all, but would take up all the free space.
How do I set up ListView
to use the available space instead of growing and pushing the views below it out of the screen?
I am looking for a solution using GridLayout
. I know it LinearLayout
will work in my case
. However, this is just a minimal test case to illustrate my problem.
I don't want to set the height programmatically if possible.
<android.support.v7.widget.GridLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:columnCount="1"
app:useDefaultMargins="true" >
<ListView
app:layout_gravity="fill" />
<TextView
android:text="TextView" />
</android.support.v7.widget.GridLayout>
source to share
This answer expands on my comments on the question and tries to explain why this cannot be done with XML via GridLayout attributes
.
The addition GridLayout
to the framework resolved a number of shortcomings regarding nested layouts, one of which was "inability to control alignment along both horizontal and vertical axes simultaneously"
as described in New Layout Widgets: Space and GridLayout by Philip Milne.
This alignment control parameter is executed layout_gravity
, description
states that option ( ). Basically this is the same as in what was also mentioned in the article: And as we know, for once the view has spanned the full height of the screen (for example in your case), underneath it will be displayed at the bottom if the layout orientation is set On ."specifies how a component should be placed
in its group of cells",
NOT within a root layout
LinearLayout
"Alignment/gravity also works just like gravity in LinearLayout..."
LinearLayouts
ListView
"vertical"
If we look at the GridLayout.LayoutParams documentation , we don't find a single parameter that would allow a component within a group of cells to adhere to a specific position of its parent layout and stay in position regardless of the size of other components within the same group; similar to the parameters layout_align[...]
for the RelativeLayout parameter.
My best guess about the lack of such parameters in GridLayout
is better alignment control compared to nested layouts.
I'm sure you know the solution to your problem using a non-attributes approach GridLayout's
. I just suggest doing this to make the answer run:
<GridLayout
... >
<RelativeLayout
... >
<TextView
...
android:id="@+id/tv"
android:layout_alignParentBottom="true" />
<ListView
...
android:layout_above="@id/tv">
</ListView>
</RelativeLayout>
</GridLayout>
source to share
You can programmatically set the height of the ListView like this:
ListView listView = (ListView) findViewById(R.id.listview);
LinearLayout.LayoutParams layoutParams = (LinearLayout.LayoutParams) listView.getLayoutParams();
layoutParams.height = listHeight;
listView.setLayoutParams(layoutParams);
listView.setAdapter(listAdapter);
However, I can't think of a way to make this scale the best for multiple devices.
source to share
If you want you can set the TextView inside the footer and then the ListView won't pop it. Although I'm not sure if this is what you want
<?xml version="1.0" encoding="utf-8"?>
<GridLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<!-- Footer aligned to bottom -->
<RelativeLayout
android:id="@+id/footer"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:background="@drawable/background"
android:gravity="center" >
<!-- TextView Here -->
</RelativeLayout>
<!-- Content below header and above footer -->
<RelativeLayout
android:id="@+id/content"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_above="@id/footer"
android:gravity="center" >
<!-- ListView Here -->
</RelativeLayout>
</GridLayout>
source to share
You should use a different layout as a parent for ListView
and TextView
and place them the way you want.
<android.support.v7.widget.GridLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:columnCount="1"
app:useDefaultMargins="true" >
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent" >
<ListView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_above="@+id/text_view_id" />
<TextView
android:id="@+id/text_view_id"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:text="TextView" />
</RelativeLayout>
</android.support.v7.widget.GridLayout>
source to share