2010-10-08 9 views
6

ich diesen Code in meinem getView verwenden:Falsches Bild in meinen Listview-Zeilen zeigt

@Override 
public View getView(int position, View convertView, ViewGroup parent) { 
    View v = convertView; 
    if (v == null) { 

     LayoutInflater vi = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
     v = vi.inflate(R.layout.listrow, null); 
    } 
    Order o = items.get(position); 

    if (o != null) { 
     TextView tt = (TextView) v.findViewById(R.id.toptext); 
     ImageView thumb = (ImageView) v.findViewById(R.id.icon); 

     if (o.getOrderDrawable() != null) { 
      thumb.setImageDrawable(o.getOrderDrawable()); 
     } else { 
      tt.setText(o.getOrderTitle()); 
     } 

    } 
    return v; 
} 

Das Problem ist beim Scrollen; manchmal wird das korrekte Bild angezeigt, aber manchmal beim Zurück-/Vorwärtsscrollen erscheinen die Bilder zufällig und sind nicht mit der Reihe verbunden.

Die Bilder werden aus dem Internet heruntergeladen.

Wie soll ich dieses Problem lösen?

Antwort

24

Android ListView wiederverwendet Listenelemente, wenn sie nicht mehr benötigt werden. Aus diesem Grund müssen Sie sicherstellen, dass alle Ansichten, die sich ändern sollten, tatsächlich geändert werden.

Ihr Problem besteht darin, dass Sie das ImageView nicht leeren oder ausblenden, wenn Sie kein Zeichenobjekt für das aktuelle Listenelement finden. Sie sollten in diesem Fall thumb.setImageDrawable(null) oder thumb.setVisibility(View.GONE) tun.

+0

Danke, das hat es gelöst! Das Problem war, dass einige meiner Bilder auf dem Webserver verschwunden waren. Danke dafür. – Curtain

+0

wenn ich Platzhalterbilder anzeigen möchte, während die Bilder aus dem Internet abgerufen werden. Wie würde ich das tun? Und welche Operation ist die teure inviate (R.layout.listrow, null)? – Karussell

+0

Vielen Dank im Voraus – Mojiiz

-1

Wenn Sie aufhören, die convertView zu verwenden, die Sie erhalten (was Sie unbedingt tun sollten), und eine ganz neue Ansicht generieren, um jedes Mal zurückzukehren, funktioniert es richtig? Ich denke, das Problem liegt in der Art, wie Sie die Ansichten wiederverwenden.

+1

nicht stoppen Ansichten Wiederverwendung. Sie müssen die Ansichten korrekt wiederverwenden, aber Sie sollten sie auf jeden Fall wiederverwenden. – Janusz

+0

Was Janusz gesagt hat. Versuchen Sie, eine Liste mit ein paar Dutzend Elementen zu erstellen, und blättern Sie durch (oder schlimmer, blättern Sie schnell durch). Ohne die Ansichten wiederzuverwenden, wird die Leistung schrecklich sein. – benvd

-1

Ich habe versucht, die hier markierte Lösung als richtig zu verwenden, aber es löst nicht das Problem des falschen Bildes beim Scrollen. Ich habe die zweite (Zsombor Erdődy-Nagy) getestet und jetzt ist es wirklich in Ordnung. So dank Zsombor :-)

Hier ist es mein Snippet:

@Override 
public View getView(int position, View convertView, ViewGroup parent) { 
    /* 
    View v = convertView; 
    if (v == null) { 
     LayoutInflater vi = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
     v = vi.inflate(R.layout.tweet_list, null); 
    } 
    */ 
    LayoutInflater vi = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
    View v = vi.inflate(R.layout.tweet_list, null); 
    final Status status = getItem(position); 
    if (status != null) { 
     TextView statusName = (TextView) v.findViewById(R.id.statusName); 
     TextView statusText = (TextView) v.findViewById(R.id.statusText); 
     TextView statusWhen = (TextView) v.findViewById(R.id.statusWhen); 
     TextView statusScreenName = (TextView) v.findViewById(R.id.statusScreenName); 
     final ImageView statusUserImage = (ImageView) v.findViewById(R.id.statusUserImage); 
     statusName.setText(status.getUser().getName()); 
     statusScreenName.setText("@" + status.getUser().getScreenName()); 
     statusText.setText(status.getText()); 
     statusWhen.setText(dateTimeFormatter.format(status.getCreatedAt())); 
     URL url = status.getUser().getProfileImageURL(); 
     String imageCacheKey = url.getPath(); 
     Drawable cachedImage = imageCache.get(imageCacheKey); 
     if (null != cachedImage) { 
      statusUserImage.setImageDrawable(cachedImage); 
     } else { 
      new DownloadImageTask(statusUserImage, imageCacheKey).execute(url); 
     } 

    } 
    return v; 
} 
+0

Hey Alex, ich hatte die gleiche Erfahrung wie du, aber dann erkannte ich, dass ich Visibility (View.GONE) für jede Ansicht (alle TextViews und ImageViews) setzen muss. Sobald ich das getan habe, konnte ich ConvertView wiederverwenden. Ich denke, es ist besser, wahrscheinlich effizienter zu verwenden, wenn möglich. – wuliwong

+0

Dies ist definitiv nicht der richtige Weg. Jedes Mal, wenn ein neues Listenelement angezeigt werden muss, erstellen Sie es vollständig von Grund auf neu. Inflayout Layouts ist eine sehr teure Operation. Sie sollten die convertView wiederverwenden. Ich bin sicher, es funktioniert, nur nicht effizient. Wenn Sie ConvertView wiederverwenden und immer noch falsche Bilder angezeigt werden, liegt das daran, dass Sie nicht alle Ansichten in Ihrem Listenelement korrekt einstellen. – benvd

Verwandte Themen