web-dev-qa-db-fra.com

Android. Comment fonctionne la méthode notifyDataSetChanged () et ListViews?

J'essaie de comprendre le concept ListView et son fonctionnement, et j'essaie de créer mon propre adaptateur qui étend BaseAdapter. Pour ArrayAdapter par exemple, il existe la méthode notifyDataSetChanged() qui devrait être appelée une fois que vous avez mis à jour la liste de tableaux contenant toutes vos données, afin d'actualiser la ListView

Mais je crée ma propre sous-classe de BaseAdapter. Cette méthode n'est pas disponible pour moi, ou est-ce? Comment puis-je implémenter cette méthode? En gros, qu'est-ce que cette méthode fait exactement, peut-être que je comprendrai alors.

Dans le cas de la ArrayAdapter, je suppose qu'il regarde quelle position la ListView affiche actuellement et il vérifie si elle est identique à celle de la ArrayList après sa mise à jour? Ou...

Il dit que la méthode:

Notifie les observateurs attachés que les données sous-jacentes ont été modifié et toute vue reflétant le jeu de données doit s'actualiser.

Mais comment cela se rafraîchit-il exactement?

Quelqu'un peut-il expliquer s'il vous plaît?

55
AndreiBogdan

Je l'ai compris. Je ne comprenais pas comment l'adaptateur avait commencé et comment il savait où obtenir les données. Lorsque j’ai étendu la classe BaseAdapter, dans le constructeur de cette classe, j’ai initialisé la liste des éléments que je voulais voir dans le ListView. Mais je ne pouvais pas comprendre comment ces valeurs seraient utilisées et quand.

Alors voila le truc !!! :

Dans BaseAdapter, certaines méthodes doivent être remplacées. Parmi ceux-ci, il y a getCount().

Lorsque le ListView est créé et ainsi de suite, il appelle getCount(). Si cela renvoie une valeur différente de 0 (j'ai renvoyé la taille de la liste de tableaux que j'avais précédemment initialisée dans le constructeur), le système appelle getView() suffisamment de fois pour remplir l'écran d'éléments. Par exemple, j'ai initialisé le ArrayList avec 20 éléments. getView() a été appelé 8 fois, demandant chaque fois le poste qu’il me fallait pour revenir (plus précisément, il voulait savoir à quoi ressemblerait la rangée dans la liste de ce données qu'il devait contenir). Si je fais défiler la liste, getView() sera appelé encore et encore, jusqu'à ce que je frappe à la fin de la liste, dans mon cas 20 éléments/lignes.

Ce que notifyDataSetChanged() fait, c’est ... lorsqu’il est appelé, il examine les éléments affichés à l’écran au moment de son appel (plus précisément les index de lignes) et appelle getView() avec ces positions. 

ie si vous affichez les 8 premiers éléments de la liste (ce sont donc ceux visibles à l'écran) et que vous ajoutez un autre élément entre le 2ème et 3ème élément de la liste et que vous appelez notifyDataSetChanged(), on appelle alors getView() 8 fois, avec des positions allant de 0 à 7, et parce que dans la méthode getView(), vous obtenez les données de ArrayList, le nouvel élément inséré dans la liste sera automatiquement renvoyé à côté de 7 sur 8 (7 et non précédent). 8 parce que le dernier élément a été déplacé d’une position vers le bas, de sorte qu’il n’est plus visible), et la variable ListView sera redessinée, ou peu importe, avec ces éléments. 

Il est également important de préciser que si vous avez correctement implémenté getView(), vous finirez par recycler les éléments (les objets) déjà affichés (au lieu d'en créer de nouveaux). Voir cette vidéo aux alentours de 12 h 00 pour voir la méthode correcte pour implémenter getView().

J'ai compris tout cela en plaçant des appels à LogCat dans chaque méthode et en suivant ce qui se passait.

J'espère que cela aidera quelqu'un qui commence tout juste à comprendre le fonctionnement de ListView.

P.S. Cet exemple m'a également beaucoup aidé à comprendre.

179
AndreiBogdan

BaseAdapter peut être "observé" par d'autres classes. Lorsque vous appelez la méthode de ListViewsetAdapter(), elle appelle registerDataSetObserver de l'adaptateur. Ainsi, l'adaptateur sait qui s'intéresse aux nouvelles données.

Vous pouvez vérifier la source de BaseAdapterici _. C'est assez petit.

notifyDataSetChanged est disponible pour vous et vous ne devriez en principe pas le remplacer (car il ne fait rien de spécial, vous pouvez donc le réutiliser dans votre propre classe).

13
Dmitry Zaytsev

Supposons que votre ListView affiche certaines données stockées dans une ArrayList.

Une fois que vous avez modifié le contenu de la ArrayList, vous devez indiquer à la liste que la source des données a été modifiée et qu'elle doit se redessiner pour afficher les nouvelles données.

C’est donc là quenotifyDatasetChanged()entre en jeu. Il indique à la ListView que les données ont été modifiées; et pour afficher les nouvelles données, la ListView doit être redessinée.

9
Swayam

Si vous étendez BaseAdapter pour la création d’une sous-classe, vous obtiendrez également la méthode notifyDataSetChanged().

0
Rupali Zambad