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?
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.
BaseAdapter
peut être "observé" par d'autres classes. Lorsque vous appelez la méthode de ListView
setAdapter()
, 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 BaseAdapter
ici _. 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).
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.
Si vous étendez BaseAdapter
pour la création d’une sous-classe, vous obtiendrez également la méthode notifyDataSetChanged()
.