24

Ich habe dieses Problem - nur für Testzwecke habe ich ParseFile zu einem der ParseObject aus der Liste empfangen. Anstatt es nur in dieser Reihe zu zeigen, zeigt es alle 4-5 Reihen, manchmal mehr, manchmal weniger. Ich bin davon überzeugt, dass die Recycling-Ansicht etwas damit zu tun hat. Seltsamerweise funktionieren andere Daten (die in diesem Beispiel gelöscht wurden) problemlos mit position Variable.Recyclerview Adapter und Glide - das gleiche Bild alle 4-5 Zeilen

@Override 
    public void onBindViewHolder(ViewHolder holder, int position) { 
     if(parseList.get(position).get("logo") != null){ 
      ParseFile image = (ParseFile) parseList.get(position).get("logo"); 
      String url = image.getUrl(); 
      Glide.with(context) 
        .load(url) 
        .placeholder(R.drawable.piwo_48) 
        .transform(new CircleTransform(context)) 
        .into(holder.imageView); 


     } 

    } 

Antwort

49

Die Antworten hier sind falsch, obwohl sie auf dem richtigen Weg sind.

Sie müssen Glide#clear() aufrufen, nicht nur das Bild auf Null setzen. Wenn Sie nicht clear() aufrufen, kann eine asynchrone Last, die nicht in der richtigen Reihenfolge ausgeführt wird, Probleme beim Anzeigen des Recyclings verursachen. Der Code sollte wie folgt aussehen:

@Override 
public void onBindViewHolder(ViewHolder holder, int position) { 
    if (parseList.get(position).get("logo") != null) { 
     ParseFile image = (ParseFile) parseList.get(position).get("logo"); 
     String url = image.getUrl(); 
     Glide.with(context) 
       .load(url) 
       .placeholder(R.drawable.piwo_48) 
       .transform(new CircleTransform(context)) 
       .into(holder.imageView); 
    } else { 
     // make sure Glide doesn't load anything into this view until told otherwise 
     Glide.clear(holder.imageView); 
     // remove the placeholder (optional); read comments below 
     holder.imageView.setImageDrawable(null); 
    } 
} 
+0

Könnten Sie mehr darüber ausarbeiten? Vorherige Antworten funktionieren gut, aber ich stelle mir vor, 'clear() 'Methode wurde nicht nur aus der dünnen Luft implementiert. –

+0

Sie arbeiten meistens nur. Wenn Sie onBindViewHolder aufrufen und eine Ladeoperation für eine Position mit einem Logo für eine bestimmte Ansicht starten, rufen Sie onBindViewHolder erneut mit demselben ViewHolder auf, bevor die Ladeoperation abgeschlossen ist. Sie sehen das alte Image anstelle einer leeren Ansicht. Diese Race-Bedingung ist viel seltener als Ihr vorheriger Fehler, aber immer noch möglich. –

+0

Auch ich sollte klarstellen, schrieb ich die Bibliothek und die Clear() -Methode. Dieser Anwendungsfall ist ein gutes Beispiel dafür, warum die Methode clear() existiert :). Sie müssen entweder immer eine neue Ladung starten (die die alte Ladung für Sie löscht) oder die Ladung selbst abbrechen, wenn Sie Ansichten wiederverwenden. –

1

Wenn "logo" den Wert null hat, wird das recycelte Bild angezeigt, anstatt es zu löschen. Fügen Sie diesen Code richtig, das Bild zu löschen:

holder.imageView.setImageDrawable(null); 
1

In RecyclerView jede Zeile mit neuen Daten zurückgeführt wird. In deinem Code stellst du ImageView nur ein, wenn es nicht null ist und sonst nichts tut. In diesem Fall, wenn es nicht null ImageView wird altes Bild seit Sie nicht override für das aktuelle Objekt angezeigt haben. Sie können dies beheben, indem Sie else condition und ImageView auf null/leer setzen.

@Override 
    public void onBindViewHolder(ViewHolder holder, int position) { 
     if(parseList.get(position).get("logo") != null){ 
      ParseFile image = (ParseFile) parseList.get(position).get("logo"); 
      String url = image.getUrl(); 
      Glide.with(context) 
        .load(url) 
        .placeholder(R.drawable.piwo_48) 
        .transform(new CircleTransform(context)) 
        .into(holder.imageView); 


     } 
     else{ 
      holder.imageView.setImageDrawable(null); 
     } 
    } 
+1

ich es wusste, dass es etwas mit Blick Recycling ist, aber nie gedacht, auf diese Weise. Vielen Dank dafür, es hat sofort funktioniert :) –

+0

Diese Antwort ist unvollständig. Sie müssen auch Glide.clear() in der fraglichen Bildansicht aufrufen, andernfalls sehen Sie möglicherweise weiterhin Probleme bei der Wiederverwendung von Zellen, wenn eine asynchrone Last später ausgeführt wird. –

+0

@samajudd Ich habe gerade das gefunden - also sollte ich sowohl 'setImageDrawable (null)' und 'Glide.clear()' aufrufen? –

2

Vielleicht müssen Sie so etwas wie dieses

.signature(new StringSignature(String.valueOf(System.currentTimeMillis()))) 

Probe versuchen:

Glide.with(context) 
       .load(url) 
       .placeholder(R.drawable.progress_animation) 
       .crossFade() 
       .signature(new StringSignature(String.valueOf(System.currentTimeMillis()))) 
       .error(R.drawable.image_error_404) 
       .into(iv); 
Verwandte Themen