2011-05-14 11 views
23

Estoy tratando de mostrar una lista de cadenas que crece dinámicamente con una casilla de verificación en un GridView, que se encuentra en TableLayout.Cómo tener un GridView que se adapta a su altura cuando se agregan elementos

Puedo mostrar estas cadenas de "casillas de verificación" bien en una fila. Mi problema ocurre cuando dejo que el usuario agregue dinámicamente nuevas cadenas en GridView.

Creé un adaptador personalizado que recibe la lista de cadenas. Digamos que tenemos n cuerdas. El adaptador devuelve 'n + 1' para el recuento de elementos; en getView, devuelve:

  • una vista con un LinearLayout, sí que tiene una casilla de verificación y un EditarTexto durante los primeros n elementos,
  • un LinearLayout con un simple botón, con un subtítulo '+' para la ' n + 1º elemento.

Hasta ahora todo bien. Cuando se hace clic en el botón '+', agrego una cadena vacía a la lista de cadenas y llamo notifyDataSetChanged en el adaptador.

El GridView se redibuja con un elemento más. PERO conserva su altura original y crea una barra de desplazamiento vertical. Me gustaría que GridView expanda su altura (es decir, ocupe más espacio en la pantalla y muestre todos los elementos).

He intentado cambiar la pantalla a LinearLayout vertical en lugar de a TableLayout, pero los resultados son los mismos.

Este es el diagrama de mi pantalla:

<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> 

El elemento casilla + cadena desde el adaptador se define así:

<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> 

El elemento '+' botón se define así:

<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> 

He intentado llamar a invalidate o invalideViews en el GridView después de agregar un elemento. También se llama invalidar en TableLayout y TableRow (en el diseño anterior de la pantalla). Sin éxito.

¿Alguna idea de por qué el GridView se niega a extender su altura?

(Nótese que estoy totalmente abierto a la utilización de otro ViewGroup que el GridView)

+0

Tengo exactamente el mismo problema: ¿alguien sabe cómo hacer esto? –

+0

Creo que puede ayudar a otros http://stackoverflow.com/a/23802813/5887689 –

+1

quizás esta respuesta pueda ayudarlo https://stackoverflow.com/questions/21482989/how-to-assign-wrap-content-as -height-to-dynamically-loaded-gridview/46350213 # 46350213 –

Respuesta

4

Cuando onMeasure() es llamado para GridView, si se MeasureSpec.UNSPECIFIED heightMode, entonces el gridview será tan alto como todos contiene elementos (más algo de relleno).

para asegurar que este es el caso, se puede hacer una vista personalizada que se extiende rápida y GridView incluyendo las siguientes anulación: solución

@Override 
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 
     super.onMeasure(widthMeasureSpec, MeasureSpec.UNSPECIFIED); 
    } 
+2

Gracias. ¿Intentó esto cuando el contenido de una celda se cambia dinámicamente? He reescrito mi código para deshacerme de GridView, por lo que no puedo probar tu respuesta. – Timores

+0

Desafortunadamente, no funciona con 'GridView' creado dinámicamente. – skywall

1

de Graham no funcionó para mí.Sin embargo este (con un poco más de la piratería) hizo: https://stackoverflow.com/a/8483078/479478

+1

¿Te importa compartir qué piratería fue necesaria para que funcione? –

4

Esto es trabajo para mí:

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

     <!-- MORE LAYOUTS IF YOU WANT --> 

    <ScrollView 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:layout_weight="1" 
    android:fillViewport="true" > 

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

       <!-- MORE LAYOUTS IF YOU WANT --> 

     <GridView 
      android:id="@+id/gridview" 
      android:layout_width="wrap_content" 
      android:layout_height="match_parent" 
      android:layout_marginBottom="10dp" 
      android:layout_marginLeft="20dp" 
      android:layout_marginRight="20dp" 
      android:layout_marginTop="5dp" 
      android:gravity="center" 
      android:horizontalSpacing="10dp" 
      android:numColumns="auto_fit" 
      android:stretchMode="columnWidth" 
      android:verticalSpacing="10dp" > 
     </GridView> 

      <!-- MORE LAYOUTS IF YOU WANT --> 

    </RelativeLayout> 

    </ScrollView> 

</RelativeLayout> 
+3

¿Realmente esta solución funciona para usted? – Umesh

+1

Esto funcionará para la altura pero no es útil para la paginación. No puede establecer la paginación usando 'android: fillViewport =" true "' en scrollview. –

46

Usar este código

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); 
    } 
} 
+4

Esto funciona bien, pero a medida que agrego muchos elementos, ahora encuentro un gran espacio vacío en la parte inferior de GridView. No podría otorgarle este espacio por ningún otro motivo, ya que lo he comprobado con la característica Mostrar rasgos del diseño de Developer Option. Por favor ayuda. –

+0

Funciona muy bien ... ¡Buen trabajo! –

+0

Si sus artículos tienen diferentes alturas, esta solución puede no funcionar correctamente. Para artículos de altura constante, esto es perfecto. –

7

he hecho de esta manera:

Este código establecerá GridView altura según número de Niño.

Nota: Donde 5 es el número de columnas.

private void setDynamicHeight(GridView gridView) { 
     ListAdapter gridViewAdapter = gridView.getAdapter(); 
     if (gridViewAdapter == null) { 
      // pre-condition 
      return; 
     } 

     int totalHeight = 0; 
     int items = gridViewAdapter.getCount(); 
     int rows = 0; 

     View listItem = gridViewAdapter.getView(0, null, gridView); 
     listItem.measure(0, 0); 
     totalHeight = listItem.getMeasuredHeight(); 

     float x = 1; 
     if(items > 5){ 
      x = items/5; 
      rows = (int) (x + 1); 
      totalHeight *= rows; 
     } 

     ViewGroup.LayoutParams params = gridView.getLayoutParams(); 
     params.height = totalHeight; 
     gridView.setLayoutParams(params); 
    } 

Espero que esto te ayude.

+1

Ahorrando mucho tiempo, gracias :) –

+0

¿Qué es ListAdapter? – dev1998

+0

@ dev1998 un componente de widget Android predeterminado. Listadapter es una interfaz como se define en https://developer.android.com/reference/android/widget/ListAdapter.html –

Cuestiones relacionadas