Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to have a GridView that adapts its height when items are added

I am trying to display a dynamically-growing list of strings with a checkbox in a GridView, which is itself in a TableLayout.

I can display these "checkboxed" strings fine in a row. My problem occurs when I let the user dynamically add new strings in the GridView.

I created a custom adapter that receives the list of strings. Say we have n strings. The adapter returns 'n + 1' for the items count; in getView, it returns:

  • a View with a LinearLayout, itself having a CheckBox and an EditText for the first n items,
  • a LinearLayout with a simple button, with a '+' caption for the 'n + 1'th item.

So far so good. When the '+' button is clicked, I add an empty string to the list of strings and call notifyDataSetChanged in the adapter.

The GridView redraws itself with one more item. BUT it keeps its original height and creates a vertical scrollbar. I'd like the GridView to expand its height (i.e. take up more space on screen and show all items).

I've tried to change the screen to a vertical LinearLayout instead of a TableLayout, but the results is the same.

Here is the layout of my screen:

<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"     android:layout_width="match_parent"     android:layout_height="wrap_content"     android:scrollbars="none"> <LinearLayout     android:layout_width="fill_parent"     android:layout_height="wrap_content"     android:orientation="vertical"     >      <!-- other lines omitted -->      <LinearLayout android:layout_width="fill_parent"                    android:layout_height="wrap_content" >         <TextView             android:layout_width="wrap_content"              android:layout_height="wrap_content"             android:text="@string/wine_rack_explanation"             android:layout_gravity="center_vertical" />           <GridView             android:layout_width="fill_parent"              android:layout_height="wrap_content"             android:id="@+id/gvRack"             android:columnWidth="90dp"                 android:numColumns="auto_fit" />     </LinearLayout>  <!-- other lines omitted -->  </LinearLayout> </ScrollView> 

The checkbox + string item from the adapter is defined like this:

<LinearLayout   xmlns:android="http://schemas.android.com/apk/res/android"   android:orientation="horizontal"    android:layout_width="wrap_content"   android:layout_height="wrap_content">     <CheckBox android:layout_width="wrap_content"               android:layout_height="wrap_content"               android:id="@+id/cbCoordinate"               android:checked="true"               />     <EditText android:id="@+id/txtCoordinate"               android:layout_width="wrap_content"               android:layout_height="wrap_content" /> </LinearLayout> 

The '+' button item is defined like this:

<LinearLayout   xmlns:android="http://schemas.android.com/apk/res/android"   android:orientation="horizontal"   android:layout_width="wrap_content"   android:layout_height="wrap_content">      <Button android:id="@+id/btnAddBottle"             android:layout_width="wrap_content"             android:layout_height="wrap_content"             android:text="@string/add_bottle_caption" /> </LinearLayout> 

I've tried to call invalidate or invalideViews on the GridView after an item is added. Also called invalidate on the TableLayout and TableRow (in the previous layout of the screen). No success.

Any idea why the GridView refuses to extend its height ?

(Note that I am completely open to using an other viewgroup than the GridView)

like image 926
Timores Avatar asked May 14 '11 22:05

Timores


1 Answers

Use this code

public class MyGridView  extends GridView {      public MyGridView(Context context, AttributeSet attrs) {         super(context, attrs);     }      public MyGridView(Context context) {         super(context);     }      public MyGridView(Context context, AttributeSet attrs, int defStyle) {         super(context, attrs, defStyle);     }      @Override     public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {         int expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2,                 MeasureSpec.AT_MOST);         super.onMeasure(widthMeasureSpec, expandSpec);     } } 
like image 83
Raj008 Avatar answered Sep 23 '22 21:09

Raj008