ListView pas rafraîchissant déjà les éléments visibles

J'affiche une liste de contacts (nom + image) à l'aide de la ListView. Afin de rendre la charge initiale rapide, je ne charge que les noms d'abord, et de reporter l'image de chargement. Maintenant, chaque fois que mon thread d'arrière-plan des finitions de chargement d'une image, il planifie ma carte notifyDataSetChanged() d'être appelé sur le thread d'INTERFACE utilisateur. Malheureusement, lorsque cela arrive, le ListView de ne pas re-rendu (c'est à dire appel getView() pour) les éléments qui sont déjà à l'écran. De ce fait, l'utilisateur ne voit pas la nouvelle image chargée, à moins qu'ils défilement et de retour pour les mêmes articles, de sorte que les points de vue sont recyclés. Quelques morceaux de code:

private final Map<Long, Bitmap> avatars = new HashMap<Long, Bitmap>();
//this is called *on the UI thread* by the background thread
@Override
public void onAvatarLoaded(long contactId, Bitmap avatar) {
avatars.put(requestCode, avatar);
notifyDataSetChanged();
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
//snip...
final Bitmap avatar = avatars.get(contact.id);
if (avatar != null) {
tag.avatar.setImageBitmap(avatar);
tag.avatar.setVisibility(View.VISIBLE);
tag.defaultAvatar.setVisibility(View.GONE);
} else {
tag.avatar.setVisibility(View.GONE);
tag.defaultAvatar.setVisibility(View.VISIBLE);
if (!avatars.containsKey(contact.id)) {
avatars.put(contact.id, null);
//schedule the picture to be loaded
avatarLoader.addContact(contact.id, contact.id);
}
}
}

AFAICT, si vous supposez que notifyDataSetChanged() causes les éléments de l'écran pour être re-créé, mon code est correct. Cependant, il semble que n'est pas vrai, ou peut-être que je suis absent quelque chose. Comment puis-je faire ce travail en douceur?

  • mieux de prendre un regard sur certains ImageLoader source ...1. set ID à la balise de ImageView 2. exécuter chargeur avec ImageView(comme la semaine ref) et l'ID que params 3. lorsque le chargeur de finir de télécharger et de décoder bitmap passer ImageView, Id et bitmap à une fonction gérée sur le thread de l'INTERFACE utilisateur 4. comparer Balise de ImageView avec ID (depuis ImageView pourraient être réutilisés) si elles sont de la même série ImageView avec le Bitmap ... vous pouvez aussi essayer d'appeler ListView.invalidateViews() pour mettre à jour visible LV éléments
  • Je suis à l'aide d'une classe dérivée de BaseAdapter, et je suis déjà en appelant notifyDataSetChanged() manuellement. De sorte que la réponse ne s'applique pas à moi.
  • Peut-être essayer d'appeler notifyDataSetInvalidated()
  • J'ai aussi pensé à garder la trace de mes ImageViews et changer leur image bitmap directement, sans s'appuyer sur getView. Mais il semble plutôt compliqué. Surtout depuis que mon code est un peu plus compliqué que je ne vais pas changer juste le ImageView, je vais changer d'autres choses (de la part de plusieurs sources de données). Je préfère avoir tous mes articles-rendu de code dans getView.
  • avez-vous lu la JavaDoc sur qui? Voici ce qu'il dit: Notifies the attached observers that the underlying data is no longer valid or available. Once invoked this adapter is no longer valid and should not report further data set changes. -- j'aimerais continuer à utiliser mon adaptateur.
  • Maintenant que j'y pense, je me souviens avoir eu des problèmes similaires concernant la mise à jour d'une liste. Quelle est la version d'Android que vous utilisez?
  • 4.3 (Nexus 4). J'ai juste essayé d'appeler invalidateViews() sur le ListView après notifyDataSetChanged(), mais il semble que la JavaDoc est source de confusion, car il ne s'est toujours pas fait redessiner le déjà des éléments de l'écran.
  • Ce problème semble très similaire à ce que j'ai (post ici: stackoverflow.com/questions/25243341/... ) . Disposez-vous également de la notifyDataSetChanged mise à jour de tous les points de vue, sauf pour le point de vue qui a un événement tactile ?

InformationsquelleAutor Felix | 2013-10-28