7
votes

Comment éviter de rafraîchir les cellules lorsque vous appelez notifyDatastetchangeed () pour PinterestLikeadapterView?

fond

J'utilise le PinterestLikeAdapterView Library strong> pour montrer des images à partir d'Internet , qui est comme une grille de grille mais avec une hauteur différente pour chaque cellule. p>

Le problème h2>

Depuis que j'utilise cette bibliothèque pour afficher des images d'Internet, il est crucial que lorsque vous appelez notifydatastetchedanged Gagné ' t causer un gâchis sur les vues. P>

Pour une raison quelconque, appeler cette fonction appellerait la méthode GeveView () avec des positions différentes pour les vues. Par exemple, même si je n'ai pas du tout défilé et appelez notifydatasetchanged (ou Addall au cas où il s'agit d'une arrayadapter), pour la position 0, il faudra quelle était la vue de la position 8, pour la position 1, il prendra la vue de la position. 7, et ainsi de suite ... p>

Ceci rend la grille entière pour rafraîchir ses images, et elle ruine l'UX. P>

généralement, dans la GridView and ListView, le moyen de Surmonter le rafraîchissement consiste à mettre la position utilisée pour la vue à l'intérieur du porte-visée et, s'ils sont égaux, cela signifie qu'ils correspondent toujours. P>

Par exemple: P>

... getView(...)
  {
  //<=inflate a new view if needed 
  //avoid refreshing view in case it's still the same position:
  if(position==holder.position)
    return rootView;
  holder.position=position;
  //<=update the view according to its data
  ...
  }

6 commentaires

Vous voulez dire que cet ordre de vue est en désordre?


Oui et non. La grille les montre d'une manière ou d'une autre. C'est juste que cela appelle l'adaptateur dans un ordre étrange. Peut-être que je n'ai pas expliqué l'exemple bien: même si je n'ai pas du tout défilé, et j'appelle NotifyDatasetchangeed (), la méthode GeveView appellera la position 0 et donnez-moi la vue de la position 8 au lieu de la vue réelle Utilisé pour la position 0. Le problème est qu'à cause de cela, je ne peux pas surmonter le rafraîchissement des vues, et il semble donc que cela puisse recharger les images. Je pense que le cache de mémoire pourrait aider, mais ce n'est pas vraiment une solution pour cela car il pourrait y avoir d'autres cas que je n'ai pas pensé.


J'ai toujours pensé qu'après notifydatasetchanged , vous n'obtenez pas d'anciennesvêtements converties dans GeveView .


@Sherifelkhatib Il l'obtiendra aussi ici, mais d'une manière étrange - pour chaque position, vous obtenez une mauvaise vue, vous ne pouvez donc pas utiliser l'état plus ancien de celui-ci lorsqu'il correspond déjà à la position. Cela signifie que la mise à jour de la cellule est inévitable dans un tel cas.


Il est parfaitement normal d'avoir une vue différente mais je pensais qu'ils devraient être nuls. Essayez ce piratage: 1- Supprimer getviewtypecount () et retour getcount (); à l'intérieur. 2- Supprimer getItemViewTtype (INT position) et position de retour; à l'intérieur de l'intérieur.


@Sherifelkhatib Je ne comprends pas comment créer de nouveaux types d'aide, car il forcera à créer des vues plus de nouvelles vues à mettre en cache. Ce dont j'ai besoin, c'est d'éviter de mettre à jour des vues quand il n'est pas nécessaire. De plus, j'utilise déjà geveviewtypEcount () et getItemviewTtype () parce que j'en ai besoin pour différents types d'informations, mais même quand c'est un seul type, je reçois le même problème.


4 Réponses :


1
votes

Affichage GeveView (Position INT, affichage, Viewgroup Parent) sera toujours appelé ascendamment, après notifyDataSetSetched () .
Je suppose que, l'ordre de terminer la tâche de téléchargement causera ce problème.
Comme vous l'avez mentionné dans votre question, la situation est un bon moyen d'éviter ce problème.

Voici une autre façon de le résoudre, réutilisez également les valeurs imageviews.

Gardez une référence faible de chaque imageview dans la tâche de téléchargement.
Ensuite, enveloppez la tâche de téléchargement dans un mannequin colordrawable .
Lorsque GeView est appelé, définissez le mannequin colordrawable sur imageview et démarrez le téléchargement. Lorsque le téléchargement est terminé, définissez l'image téléchargée dans le imageview référencé dans oignostexecute () .

Explication
http://android-developers.blogspot.jp/2010/07 /MULTHReading-for-Performance.html
Code source
https://code.google.com/p/android-Imagedownloader/source/checkout


1 commentaires

Aucune tâche n'a rien à voir avec ça. Les tâches seront réellement annulées depuis que la position de GeveView ne correspond pas à l'un des porte-visés. Ce qui se passe ici, c'est quelque chose comme le défilement, même si aucun défilement n'a été effectué. En tant que note latérale, j'aimerais connaître un peu plus sur l'idée que vous avez présentée, mais elle ne peut pas résoudre le problème que j'ai montré.



2
votes

réponse courte :

Utilisez une bibliothèque de chargement d'image comme Picasso qui met en cache les images les plus récemment utilisées en mémoire, alors ils ne Il faut être rechargé du réseau.

réponse longue:

Adapterview fait quelque chose appelé Voir Recyclage, où Vues qui ne sont plus nécessaires pour afficher une position sont réutilisées pour afficher une autre. (Par exemple, comme vous faites défiler vers le bas, vues qui disparaissent hors du haut de l'écran sont réutilisés pour de nouvelles positions au bas de l'écran.) À cause de cela, c'est normal pour GeveView ( ) à passer la même vue pour plus d'une position.

Ceci est fait pour des raisons de performances: gonfler de nouveaux Vues est difficile et prend du temps, donc Adapterview essaie de le faire rarement que possible.

Lors de l'utilisation d'un support, vous stockez des références à imageview et TextView Enfants à l'intérieur de l'élément Voir , donc vous n'avez donc pas à regarder les haut avec wederviewide () à chaque fois - vous ne stockez généralement rien de spécifique à une position particulière, car la vue et son support souvent être utilisé pour différentes positions.

Maintenant, lorsque vous appelez notifydatastetchanged () , Adapterview suppose que le jeu de données a complètement changé. L'image associée à la position 8 peut ne plus être présente ou elle peut être associée à la position 12 maintenant. En conséquence, tous les vues sont supprimés - mais parce que Adapterview Voulaient toujours éviter de gonfler de nouveaux Vues , ils sont ré-utilisés pour afficher les nouvelles données, sans égard pour quelle position ils affichaient précédemment.

Ceci explique pourquoi GeveView () est adopté le même Vue pour différentes positions et pourquoi les positions visibles sont en cours de rafraîchissement lorsque vous appelez notifydatastetched () < / code>. Mais comment éviter de faire rafraîchir vos images, ruiner l'expérience utilisateur?

Utilisez une bibliothèque de chargement d'image comme Picasso qui met en cache les images les plus récemment utilisées en mémoire, alors ils ne Il faut être rechargé du réseau. L'actualisation se produira encore, mais ce sera instantané.


2 commentaires

Je connais la manière dont l'Adapterview fonctionne et j'ai utilisé la position dans le porte-visée pour éviter tout rafraîchissement des vues qui sont déjà synchronisées avec les données. Le problème est que cette astuce ne fonctionne pas sur cette bibliothèque car elle dégage avec l'ordre des vues, même si aucune défilement n'a été effectuée. à propos de la bibliothèque que vous avez suggérée, il semble sympa, mais je ne suis pas sûr de pouvoir aider puisque je dois avoir le fichier à la fois de petite taille et de grande taille (adapté à l'écran), donc je télécharge le fichier et ensuite faire le fichier. rédaction en conséquence. Lorsque vous appuyez sur une image, il permettra de montrer la version complète de celle-ci.


Merci beaucoup.. !! Son amende fonctionnant quand j'ai utilisé Picasso au lieu de Glide et un chargeur d'image universel.



0
votes

Il y a un très bon exemple sur Pinterestlikelistview dans github

Voici la bibliothèque STANCEPTEDGRIVView

une version modifiée d'Android's Expérimental StaggeredView. Inclut propre OnItemClickListener et OnitemLongClickLicklistener, sélecteur et restauration de position fixe.

Vous pouvez obtenir un projet de bibliothèque ici ici Bibliothèque

Et vous pouvez obtenir démo projet ici

C'est un très bon projet open source, vous pouvez donc utiliser au lieu de PinterestLikeadapterView < / a>

Entrez la description de l'image ici

J'espère que cette bibliothèque va vous aider.



0
votes

semble que les auteurs de cette bibliothèque l'ont réparée, après un certain temps, j'ai signalé à ce sujet:

https://github.com/huewu/pinterestlikeadapterview/issues/8 < / p>


0 commentaires