web-dev-qa-db-fra.com

Comment mettre GridView dans ScrollView

Je dois concevoir une disposition telle que toute la disposition doive défiler et une disposition interne. Je dois afficher le contenu associé sous la forme Grid. J'ai donc décidé d'utiliser GridView. Mais le problème est que je ne parviens pas à utiliser GridView dans ScrollView. J'ai lu la documentation (documentation également en disant que nous ne devrions pas utiliser GridView dans ScrollView) aussi.Mais je dois le faire, alors pouvez-vous me donner une idée à ce sujet.Merci

63
Dilip

GridView présente des avantages indéniables à côté du défilement inhérent. Par exemple, une mise en page dynamique et cohérente de cellules qui se développera et se contractera en fonction des données que vous lui transmettez. Donc, quand les gens disent que ce n'est pas bien de vouloir une telle fonctionnalité, je pense que c'est faux, car vous pourriez vouloir la grille dynamique d'images (vues) à l'intérieur d'une vue défilante, mais que cette vue défilante entière contienne autre chose que la grille. cellules. 

Maintenant, voici comment vous pouvez le faire. Vérifiez la réponse ici . C'est un GridView à hauteur extensible, que vous voudrez importer/créer dans votre projet. Ce que cela signifie fondamentalement, c’est que plus d’éléments sont ajoutés à GridView, plus sa hauteur sera augmentée, au lieu de conserver sa hauteur définie et le défilement. C'est exactement ce que vous voulez.

Une fois que vous avez la propriété ExpandableHeightGridView dans votre projet, accédez à votre structure XML où vous souhaitez que GridView se trouve. Vous pouvez ensuite faire quelque chose comme ceci (en paraphrasant):

<ScrollView ...>
    <RelativeLayout ...>
        <com.example.ExpandableHeightGridView ... />
        <other view items />
    </RelativeLayout>
</ScrollView>

Ensuite, dans votre activité où vous définissez l'adaptateur de GridView, vous voulez vous assurer que vous le définissez pour se développer. Alors:

ExpandableHeightGridView gridView = (ExpandableHeightGridView) findViewById(R.id.myId);
gridView.setAdapter(yourAdapter);
gridView.setExpanded(true);

La raison pour laquelle vous souhaitez utiliser ce GridView extensible est due au fait qu’un GridView standard n’est pas développé, c’est ce qui le fait défiler. Il reste à une certaine hauteur et, au fur et à mesure que le nombre d'éléments le remplit au-delà des limites de sa vue, il devient déroulable. Maintenant, avec cela, votre GridView augmentera toujours sa hauteur pour s’adapter au contenu qu’il contient, ne lui permettant ainsi pas de passer en mode de défilement. Cela vous permet de l'utiliser à l'intérieur de ScrollView et d'utiliser d'autres éléments de vue au-dessus ou au-dessous de celui-ci dans ScrollView et de les faire défiler.

Cela devrait vous donner le résultat que vous recherchez. Faites moi savoir si vous avez des questions.

106
dennisdrew

Je sais que je suis en retard mais j'ai une autre solution que je dois partager et qui fonctionne parfaitement. Ici, la méthode calcule la hauteur de GridView en fonction du nombre d'éléments qu'il contient et la définit sur GridView au moment de l'exécution. 

public void setGridViewHeightBasedOnChildren(GridView gridView, int columns) {
        ListAdapter listAdapter = gridView.getAdapter(); 
        if (listAdapter == null) {
            // pre-condition
            return;
        }

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

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

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

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

}

Après avoir appelé setAdapter sur votre gridview, appelez simplement 

setGridViewHeightBasedOnChildren( <yourGridView> , <no of grid view columns> )

et ça va marcher.

Vous pouvez définir la grille dans votre XML comme vous le faites normalement

et laissez le code s'en occuper. :)

32
Vikram Gupta

J'ai trouvé un moyen de donner au GridView une taille fixe dans ScrollView , et permettre le défilement it. Cela vous permet de voir l'intégralité de ScrollView sans avoir à faire défiler tous les éléments de GridView, et il est plus logique pour moi que d'utiliser ExpandableHeightGridView.

Pour ce faire, vous devez implémenter une nouvelle classe étendant GridView et remplacer onTouchEvent () pour appeler requestDisallowInterceptTouchEvent (true) ..____. Ainsi, la vue parent laissera les événements tactiles d'interception de grille.

GridViewScrollable.Java:

package com.example;
import Android.content.Context;
import Android.util.AttributeSet;
import Android.view.MotionEvent;
import Android.widget.GridView;

public class GridViewScrollable extends GridView {

    public GridViewAdjuntos(Context context) {
        super(context);
    }

    public GridViewAdjuntos(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public GridViewAdjuntos(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

    @Override
    public boolean onTouchEvent(MotionEvent ev){
        // Called when a child does not want this parent and its ancestors to intercept touch events.
        requestDisallowInterceptTouchEvent(true);
        return super.onTouchEvent(ev);
    }
}

Ajoutez-le dans votre mise en page avec les caractéristiques et les marges de votre choix, dans un ScrollView:

<ScrollView xmlns:Android="http://schemas.Android.com/apk/res/Android"
xmlns:tools="http://schemas.Android.com/tools"
Android:layout_width="match_parent"
Android:layout_height="match_parent"
Android:isScrollContainer="true" >

    <com.example.GridViewScrollable
    Android:id="@+id/myGVS"
    Android:layout_width="wrap_content"
    Android:layout_height="wrap_content"
    Android:gravity="center"
    Android:numColumns="auto_fit"
    Android:stretchMode="columnWidth" />

</ScrollView>

Et obtenez-le dans votre activité:

GridViewScrollable myGridView = (GridViewScrollable) findViewById(R.id.myGVS);

J'espère que ça aide =)

10
Lionel T.

Pour utiliser gridview dans scrollview, définissez scrollview Android: fillViewport = "true" 

Je sais qu'il est tard pour répondre ici, mais peut être utile à certains nouveaux développeurs.

2

Si vous avez utilisé la réponse de dennisdrew et que vous avez du contenu au-dessus de votre grille, il est masqué lorsque vous ouvrez votre vue, ajoutez simplement la dernière ligne ci-dessous

ExpandableHeightGridView gridView = (ExpandableHeightGridView) findViewById(R.id.myId);
gridView.setAdapter(yourAdapter);
gridView.setExpanded(true);
gridView.setFocusable(false);
1
aidan sliney

Il vaut mieux utiliser ExpandableHeightlistView ou ExpandableHeightGridView dans scrollview.

Logique

Calculez toute la hauteur en fournissant un indice de hauteur très élevé. Mais n'utilisez pas les 2 bits les plus élevés de cet entier; ceux-ci sont réservés au mode MeasureSpec.

int expandSpec = MeasureSpec.makeMeasureSpec(
 Integer.MAX_VALUE >> 2, MeasureSpec.AT_MOST);
 super.onMeasure(widthMeasureSpec, expandSpec);

 ViewGroup.LayoutParams params = getLayoutParams();
 params.height = getMeasuredHeight();

pour plus d'informations, explorez l'exemple ci-dessous avec démonstration

http://www.londatiga.net/it/programming/Android/make-Android-listview-gridview-expandable-inside-scrollview/

1
Kishore Reddy

Je cherchais également à faire défiler une vue de grille dans une vue de défilement imbriquée.

Cette réponse à une autre question m'a aidé: https://stackoverflow.com/a/38612612

Activer votre propriété GridView en tant que

Android:nestedScrollingEnabled="true"

Affiche originale: Droid_Dev

1
Stephen Emery

je ne forcerais pas la question. GridView ne fonctionne pas bien dans un scrollView. au lieu de cela, convertissez votre gridview en une vue recyclée et utilisez un gridLayoutManager pour résoudre le problème. 

0
j2emanue