2010-09-10 6 views
4

J'ai un GridView à l'intérieur d'un LinearLayout à l'intérieur d'un ScrollView qui pages dans les données du serveur. Sous le GridView est un bouton pour charger plus de données. Mon GridView aura une hauteur ultime qui est plus grande que l'écran. Si je mets la taille de ma GridView à wrap_content ou à parent_fill, elle se positionne elle-même à la hauteur exacte disponible à l'écran et ne défile pas du tout, remplaçant les lignes supplémentaires. Si je définis explicitement layout_height sur quelque chose de grand, comme 1000dip, le défilement se comporte correctement, mais je ne peux pas prédire la hauteur finale de ma vue de défilement a priori.Comment puis-je calculer la hauteur requise d'un GridView à l'intérieur d'un ScrollView sur Android?

Comment est-ce que je détermine par programme la taille nécessaire d'un GridView pour obtenir le comportement désiré?

Voici ma mise en page ci-dessous. Comme vous pouvez le voir, je régler la hauteur à 1000dip, mais qui est faux, j'ai besoin de cette valeur pour se régler automatiquement/programme:

 <ScrollView 
    android:layout_width="fill_parent" 
    android:layout_height="fill_parent" 
    android:fillViewport="true"   
    android:layout_weight="1"  
    > 
     <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
      android:layout_width="fill_parent" 
      android:layout_height="wrap_content" 
      android:orientation="vertical"  
      > 

      <GridView xmlns:android="http://schemas.android.com/apk/res/android" 
       android:id="@+id/grid" 
       android:layout_width="fill_parent" 
       android:layout_height="1000dip" 
       android:columnWidth="70dp" 
       android:numColumns="auto_fit" 
       android:verticalSpacing="0dp" 
       android:horizontalSpacing="0dp" 
       android:stretchMode="columnWidth" 
       android:gravity="center" 
       android:background="#000000" 
       android:layout_weight="1" 
      /> 
      <Button 
      android:id="@+id/load_more" 
      android:layout_width="fill_parent" 
      android:layout_height="wrap_content" 
      android:text="Load More Foo" 
      /> 
     </LinearLayout> 
    </ScrollView> 

Répondre

1

GridViews Apparemment, à l'intérieur ScrollViews ne sont pas casher dans la terre Android. Passer à ListView avec des lignes personnalisées. Cela semble mieux se passer.

+0

FYI J'ai effectivement écrit mon propre widget d'interface utilisateur similaire à GridView en utilisant ListViews, et ça marche très bien. – esilver

14

Voici une façon de le faire, si quelqu'un en a besoin. Un peu un hack mais fait l'affaire. Vous devez définir GridView d'abord assez grand pour tous les points de vue (par exemple 10000dip)

final GridView imageContainer = // your GridView 
imageContainer.getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() 
      { 
      @Override 
      public void onGlobalLayout() 
       { 
       imageContainer.getViewTreeObserver().removeGlobalOnLayoutListener(this); 
       View lastChild = imageContainer.getChildAt(imageContainer.getChildCount() - 1); 
       imageContainer.setLayoutParams(new LinearLayout.LayoutParams(LayoutParams.FILL_PARENT, lastChild.getBottom())); 
       } 
      }); 
+0

Incroyable piratage! Ça marche. – deviant

+0

Quel hack mec !!!!! ... remarquable ... –

2

Je sais qu'il est un vieux cas, mais j'eu un problème similaire où mon ScrollView contenait plusieurs LinearLayout s, qui, à leur tour, contenait une en-tête et un GridView. Fondamentalement, j'ai fait des sections catégorisées avec des en-têtes contenant des images appartenant à cette catégorie. Le GridView devait avoir une hauteur flexible.

J'ai trouvé beaucoup de réponses à propos de la substitution de onMeasure(), mais cela ne fonctionnait que sur certains périphériques, pas tous. La hauteur serait éventuellement 1, ou 3 ou juste 0, affichant seulement quelques pixels de l'image.

StretchingGridView classe

Je l'emporterait sur la méthode drawableStateChanged() avec ce code, inspiré par @ solution de Karitsa:

@Override 
public void drawableStateChanged() { 
    getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() { 

     @Override 
     public void onGlobalLayout() { 
      getViewTreeObserver().removeOnGlobalLayoutListener(this); 
      View lastChild = getChildAt(getChildCount() - 1); 
      if (lastChild != null) { 
       int height = Math.max(lastChild.getBottom(), getColumnWidth()); 
       float child = getAdapter().getCount(); 
       float col = getNumColumns(); 
       int rows = (int) Math.ceil(child/col); 
       height = rows * getColumnWidth() + (getHorizontalSpacing() * rows-1); 
       setLayoutParams(new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT, height)); 
      } 
     } 
    }); 
} 

Note: Mon GridView utilise des images carrées, je fonde la hauteur sur leur largeur . Je ne pense pas que cela fonctionne bien avec des hauteurs d'éléments de grille flexibles.