3 Stimmen

Android - Gridview Bilder mischen beim Scrollen

Ich habe ein GridView, das zwei Spalten ImageViews anzeigt. Ich lade diese Bilder mit einer AsyncTask (siehe diesen Beitrag Lazy load of images in ListView).

Aber wenn ich im GridView scrolle, werden die Bilder in den Positionen vermischt. Zum Beispiel zeigt das 14. Bild das 1. Bild an, ich denke, die Ansicht versucht, das alte Bild anzuzeigen, bevor die AsyncTask beendet ist.

Mein Code:

    public Content getItem(int position) {
        return contents.get(position);
    }

    public long getItemId(int position) {
        return position;
    }

    @Override 
    public boolean hasStableIds() { return true; }

    public View getView(int position, View convertView, ViewGroup parent) {
        Thumbnail contentView;
        Content current = contents.get(position);
        if (convertView == null) {
            contentView = new Thumbnail(mContext);  
        }
        else {
            contentView = (Thumbnail) convertView;
        }

        contentView.title = current.getTitle();
        contentView.image = current.getImage();
        contentView.link = current.getLink();
        contentView.init();

        return contentView;
    }

Init Funktion

    TextView titleText = (TextView)super.findViewById(R.id.titleText);
    titleText.setText(title);

    ImageView imageControl = (ImageView)super.findViewById(R.id.thumbImage);
    DrawableManager loadImage = new DrawableManager();              loadImage.fetchDrawableOnThread(imgUrl, imageControl);

Ich warte auf deine Hilfe

Danke

3voto

Andrei Buneyeu Punkte 6618

Es geschieht aufgrund der Ressourcenwiederverwendung. Was Sie tun sollten:

  1. Zuerst legen Sie einfach ein Standardbild für Ihre imageView fest (contentView.image.setImageResource(DEFAULT_RESOURCE)) innerhalb der getView Methode (ein Übergangsbild ist besser als das falsche).

  2. Setzen Sie einen eindeutigen Tag für Ihr Bild, zum Beispiel die Position oder die URL des zu ladenden Bildes (contentView.image.setTag(url)). Wenn der AsyncTask fertig ist, können Sie einige Überprüfungen durchführen wie

    String url=(String)imageView.getTag();
    
    if (url.equals(mUrl)) { //mUrl kann separat an die AsyncTask-Instanz übertragen werden
        mActivity.runOnUiThread(new Runnable() {
    
        @Override
        public void run() {
            imageView.setImageDrawable(bmp);
        });
    });
    }

Das ist notwendig, da der Adapter keinen Speicher für alle N ImageView für N Elemente zuweist. Er speichert nur die benötigte Menge für sichtbare Elemente und einige reservierte ImageViews. Daher gibt es keine Garantie dafür, dass die ImageView-Referenz, die Sie speichern, innerhalb von Sekunden aktuell sein wird, da sie unsichtbar werden und von sichtbaren Elementen wiederverwendet werden kann.

0voto

richardwiden Punkte 1548

Laden Sie die Bilder nicht selbst. Verwenden Sie Universal Image Loader. Es kann Bilder und geladene Bitmaps zwischenspeichern. Damit verschwindet Ihr Problem. Es unterstützt auch das Anzeigen von Ersatzbildern und automatisches Anhalten beim Scrollen und so weiter.

Es löst Ihre spezifischen Probleme, indem es nur das Bild für die letzte Instanz einer imageView lädt, wenn Sie es wiederverwenden.

imageLoader.displayImage(imageUri, imageView);

Es ist alles, was benötigt wird, um ein Bild asynchron zu laden.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X