Android ListView aktualisieren von Miniaturbildern mit AsyncTask Verursacht View recycling
Habe ich versucht zu bekommen, thumbnails, um die Arbeit mit einem AsyncTask für die Bild-Dateien in einem ListView.
Ich habe das gleiche problem, Zeile Recycling, und damit auf scrolling thumbnails zugeordnet falschen Zeilen. Ich habe versucht, hinzufügen von tags, um die Bildansicht und dann die Bestätigung der tags in der onPostExecute() in der AsyncTask, aber jedoch waren Sie erfolglos bei meinen versuchen. Jemand bitte helfen!
Den benutzerdefinierten adapter ist wie folgt :
public class MySimpleAdapter extends SimpleAdapter {
public MySimpleAdapter(Context context,
List<? extends Map<String, ?>> data, int resource,
String[] from, int[] to) {
super(context, data, resource, from, to);
//TODO Auto-generated constructor stub
}
public View getView(int position, View convertView, ViewGroup parent) {
final View v = super.getView(position, convertView, parent);
thumbnail = (ImageView) v.findViewById(R.id.thumbnail);
checker = (CheckBox) v.findViewById(R.id.checkBox);
filenametext = (TextView) v.findViewById(R.id.text1);
String pathtoimage = startLocation.concat("/"
+ filenametext.getText().toString());
desctext = (TextView) v.findViewById(R.id.text2);
String temp = desctext.getText().toString();
if (temp.equals("Directory") == true) {
checker.setEnabled(false);
switch (theme) {
case 0:
thumbnail.setImageResource(R.drawable.folder_light);
break;
case 1:
thumbnail.setImageResource(R.drawable.folder_dark);
break;
}
} else {
checker.setEnabled(true);
if (filenametext.getText().toString().endsWith(".jpg")
|| filenametext.getText().toString().endsWith(".png")
|| filenametext.getText().toString().endsWith(".bmp")) {
Boolean hashmapfound = false;
for (HashMap.Entry<String, Bitmap> entry : thumbnaillist
.entrySet()) {
String key = entry.getKey();
if (key.equals(filenametext.getText().toString())) {
Log.d(TAG, "HashMapKey Found!");
thumbnail.setImageBitmap(entry.getValue());
hashmapfound = true;
}
}
if (!hashmapfound) {
Log.d(TAG, "NO HashMapKey Found! Adding to HashMap!");
switch (theme) {
case 0:
thumbnail
.setImageResource(R.drawable.unknown_image_light);
break;
case 1:
thumbnail
.setImageResource(R.drawable.unknown_image_dark);
break;
}
thumbnail.setTag((filenametext.getText().toString()));
new GetBitMaps(thumbnail).execute(pathtoimage,
filenametext.getText().toString());
}
} else {
switch (theme) {
case 0:
thumbnail.setImageResource(R.drawable.file_light);
break;
case 1:
thumbnail.setImageResource(R.drawable.file_dark);
break;
}
}
}
return v;
}
}
Den AsyncTask ist wie folgt :
class GetBitMaps extends AsyncTask<String, Void, Bitmap> {
private ImageView thumbnail;
private String imageName;
public GetBitMaps(ImageView thumb) {
//TODO Auto-generated constructor stub
thumbnail = thumb;
}
@Override
protected Bitmap doInBackground(String... pathtoimage) {
Bitmap bmp = createThumbnail(pathtoimage[0]);
thumbnaillist.put(pathtoimage[1], bmp);
imageName = pathtoimage[1];
return bmp;
}
@Override
protected void onPostExecute(Bitmap bmp) {
if (((String) thumbnail.getTag()).equals(imageName)) {
thumbnail.setImageBitmap(bmp);
}
}
private Bitmap createThumbnail(String filepath) {
Bitmap bmp = BitmapFactory.decodeFile(filepath);
int w = bmp.getWidth();
int h = bmp.getHeight();
if (w > h) {
w = 80;
h = 40;
} else if (w < h) {
w = 40;
h = 80;
}
bmp = Bitmap.createScaledBitmap(bmp, w, h, true);
return bmp;
}
}
Kann ich immer noch nicht herausfinden, was zu tun ist, um die Miniaturansichten anzuzeigen, an die richtigen Zeilen BEIM SCROLLEN.
Bitte Beachten Sie: Nach dem scrollen Weg von der betroffenen Zeilen zu scrollen und wieder zurück, Dinge, die funktionieren, aber das scrolling-problem ist nicht Weg!
InformationsquelleAutor Daksh | 2012-07-27
Du musst angemeldet sein, um einen Kommentar abzugeben.
Vom in diesem blog-post:
Was Sie tun möchten ist, laufen alle pro-row IO oder keine schweren CPU-gebunden-routine, die asynchron in einem separaten thread. Der trick hier ist, zu tun, und dann noch den ListView-recycling-Verhalten. Zum Beispiel, wenn Sie einen AsyncTask, um ein Profil laden, das Bild des Adapters getView(), die Ansicht, die Sie laden das Bild möglicherweise wiederverwendet werden für eine andere position, bevor der AsyncTask beendet ist. So, Sie benötigen einen Mechanismus, um zu wissen, ob die Ansicht der bisher nicht recycelt, wenn Sie fertig sind mit dem asynchronen Betrieb.
Einen einfachen Weg dies zu erreichen ist, befestigen Sie einige information zu der Ansicht, dass es erkennt, welche Zeile zugeordnet ist. Dann können Sie überprüfen, ob die Ziel-Zeile für die Ansicht ist immer noch die gleiche, wenn der asynchrone Vorgang abgeschlossen ist. Es gibt viele Möglichkeiten, dies zu erreichen. Hier ist nur eine vereinfachte Skizze einer Weise, die Sie es tun könnte:
Ich bin mir nicht sicher, was könnte die Ursache dieses neue problem; ich schlage vor, Sie veröffentlichen eine neue Frage. Aber ich habe eine bessere Implementierung, die Sie vielleicht in der Lage sein, aus der Android-Entwickler-Blog. Komplettes demo-Projekt ist hier.
Jeff, könnten Sie bitte post das ganze getView () - Funktion? Ich versuche es zu implementieren, und nur das erste element des ListView-Steuerelements aktualisiert wird, sieht aus wie ich haben problem Wiederverwendung der views
Haben Sie zu recyceln/entsorgen Sie die bitmap, wenn es nicht die richtige mPosition in onPostExecute?
was ist der cursor ? und was zurück ?
InformationsquelleAutor Jeff Axelrod
Mithilfe der AsyncTask.THREAD_POOL_EXECUTOR wil Ende laufen mehrere threads Holen sich die thumnails.
Es gibt keine Reihenfolge, in der Weise, die Sie ausführen oder finisch und legen Sie das Bild für die Ansicht. Beim scrollen hin und her, Sie können am Ende mit dem falschen Bilder in Ihren Ansichten.
Getestet habe ich den AsyncTask.THREAD_POOL_EXECUTOR und es führt zu dem falschen Bild für einige Ansichten.
InformationsquelleAutor user1439970
können Sie versuchen, die vorbeifahrenden ListView in dein Adapter Konstruktors von Ihrer Aktivität (eventuell auch in Ihrem async task hängt davon ab, wie Sie möchten, um es zu implementieren).
und vergleichen Sie die position mit getFirstVisiblePosition() und getLastVisiblePosition() gegen Ihre
mPosition
InformationsquelleAutor Pete