8
votes

Problème de défilement GridView sur Android

Cela doit être quelque chose très simple, je suis négligé, mais j'ai le problème suivant (le poteau est plutôt long, mais je veux fournir autant d'informations que possible :)).

J'ai une grille de grille dans mon Application Android où chaque cellule contient la vue personnalisée: p> xxx pré>

et chaque cellule est p> xxx pré>

mon adaptateur ressemble à ceci:

public class ImageAdapter extends BaseAdapter {
    private List<String> mPictures = null;

    public ImageAdapter(List<String> pictures) {
         mPictures = pictures;
    }

    public int getCount() {
          return mPictures != null ? mPictures.size() : 0;
    }
    public Object getItem(int position) {
          return mPictures != null ?  mPictures.get(position) : null;
    }
    public long getItemId(int position) {
          return mPictures != null ? position : -1;
    }
    @Override
    public View getView(int position,View convertView,ViewGroup parent) 
    {
        ImageThumbView i = null;
        try
            {               
            Thread.sleep(100);

            if (convertView == null) 
            {
                String path = mPictures.get(position);
                Log.d(((Integer)position).toString(), path);
                i = addSingleView(_li, path);
                TextView idx = (TextView) i.findViewById(R.id.caption);
                if (idx != null)
                    idx.setText(((Integer)position).toString());
            }
            else 
            {
                Log.d(((Integer)position).toString(), "ALREADY NOT NULL");
                i = (ImageThumbView) convertView;
                                    // These 2 lines were added only in desperate attempt to get it working, but it makes no difference
                String path = mPictures.get(position);
                i.updateView(path);
            }
        }
        catch(InterruptedException ie)
        {
            ie.printStackTrace();
        }
    return i;
        }
}


5 Réponses :


10
votes

La réponse est la réponse du recyclage.

En général, votre getsView doit toujours être quelque chose du formulaire: xxx

où votre classeur On dirait quelque chose comme xxx

alors vous ne devriez pas rencontrer aucun problème. De plus, je ne suis pas sûr de savoir pourquoi vous aviez besoin de dormir dans votre gantView? Cela ralentira le défilement de votre grilleview.


5 commentaires

Ok, je crois que c'était la vue du recyclage qui a tué mon code d'origine. Merci beaucoup!


En fait, j'ai pris trop tôt. La solution proposée ne fonctionne pas car la principale différence entre elle et le code que j'ai utilisé est qu'il définit des tiroirs prédéfinis. Mais au moins je vois maintenant le problème.


J'ai changé mon code pour espérer mieux votre cas d'utilisation. Faites-moi savoir si c'est mieux.


Salut! J'ai le même code que vous avez mais je rencontre toujours l'image aléatoire lors du défilement. Est-ce un bug connu sur GridView?


Si (ConvertView == Null) {Cette partie est très importante. Évité mon problème java.lang.outofMemororyError dans mon adaptateur personnalisé.



21
votes

En réalité, le problème ici est que vous définissez le contenu de la "convertieview" dans le cas échéant ou d'autre. Ou vous devez toujours le faire après instanciation de la vue si elle est nulle et définissez le contenu uniquement avant de renvoyer la vue.

Par conséquent, vous êtes sûr que le contenu de la vue est toujours le bon, mis à jour à l'aide de la position et non une fausse vue recyclée. P>

Donc, vous devriez en général parler, procédez comme suit:
(Basé sur le tutoriel du guide Android ici ) P>

public View getView(int position, View convertView, ViewGroup parent) {
    ImageView imageView;
    if (convertView == null) { 
        imageView = new ImageView(mContext);
        //just creating the view if not already present
    } else {
        imageView = (ImageView) convertView;
        //re-using if already here
    }

    //here is the tricky part : set the content of the view out of the if, else
    //just before returning the view
    imageView.setImageResource(mThumbIds[position]);
    return imageView;
}


1 commentaires

J'avais le même problème mais n'était pas capable de comprendre que, mais vous me faites comprendre que le problème remercie, je reçois maintenant le code MA qui travaille en faisant convertieView == null à chaque fois sur rafraîchir la grille merci



0
votes

Je rencontre le même problème. Je me déplace dans la direction de rendu des vues en arrière-plan;

J'étudie ces codes, si vous devriez aider:

http://blog.tomgibarara.com/post/7665158012/ Android-Adapter-Vue-Rendu

https://github.com/desertjim/lazyloadinggridview


0 commentaires

-8
votes

Les gars pour éviter ce problème renvoient toujours un objet nouvellement créé dans GeveView ()

public View getView(int position, View convertView, ViewGroup parent) {
                ImageView       imageView;
                TextView        textView;
                LinearLayout    linearlayout  = new LinearLayout(mContext);
                //if (convertView == null) {
                    imageView       = new ImageView(mContext);
                    textView        = new TextView(mContext);

                    //imageView.setLayoutParams(new GridView.LayoutParams(85, 85));
                    imageView.setAdjustViewBounds(false);
                    imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
                    imageView.setPadding(4, 8, 8, 8);                   
                    imageView.setBackgroundResource(mThumbIds[position]);

                    textView.setText(mThumbText[position]);                
                    textView.setGravity(0x01);
                    textView.setMaxLines(2);

                    //textView.setPadding(20, 0, 0, 0);
                    linearlayout.addView(imageView,0);
                    linearlayout.addView(textView,1);
                    linearlayout.setPadding(4, 4, 4, 4);
                    linearlayout.setOrientation(LinearLayout.VERTICAL);
                    linearlayout.setGravity(0x01);

               // } else {
                    //linearlayout = (LinearLayout) convertView;
                //}

                return linearlayout;
            }


1 commentaires

C'est une très mauvaise idée de retourner un nouvel objet dans chaque GeveView (). Cela fera bégayer votre liste lorsque vous faites défiler votre défilement et provoquer une collecte excessive des ordures.



3
votes

Utilisez le chargeur paresseux standard pour obtenir les images mais ne jamais mettre à jour surpostexecute, ce qui provoque la mise à jour des images trop rapidement et obtenez le hasard que vous ne désirez pas.

J'ai même utilisé le code: xxx

int L'onpostexecute qui mettrait ensuite à jour les images correctement pour le premier écran, mais si vous retournez l'écran d'images, puis revenez aussi Rapidement au premier écran, obtenez le hasard à nouveau, donc j'utilise maintenant le: xxx

pour mettre à jour la vue.


0 commentaires