web-dev-qa-db-fra.com

Ce qui est mieux? notifyDataSetChanged ou notifyItemChanged en boucle?

J'ai donc une activité avec RecyclerView et je souhaite changer TextView de chaque élément du fichier RecyclerView en appuyant sur le bouton ayant onClickListener() dans l'activité.

Je me demande ce qui est meilleur en termes de performance:

  1. Utilisez notifyDataSetChanged ceux.
  2. Utiliser une boucle avec une condition telle que int i est inférieur à List.size()notifyItemChanged serait appelé quelques fois.

Dans les deux cas, je crée une variable booléenne dans RecyclerView adaptateur qui est utilisé par onBindViewHolder pour savoir comment mettre à jour un élément. Par défaut, c'est faux et après un clic sur le bouton, il devient vrai, donc onBindViewHolder met à jour l'élément de manière différente.

J'aimerais aussi savoir si cette approche est appropriée.

47
Daniel

Si vous mettez simplement à jour une partie de la vue, utilisez notifyItemRangeChanged() ou notifyItemChanged() à la place de notifiyDataSetChanged(). La différence ici concerne les changements structurels et les changements d’éléments . C’est dans la documentation Android développeurs RecyclerView.Adapter Trouvée) ici .

Voici une autre information sur les différences entre les deux types de changements:

Il existe deux classes différentes d'événements de modification de données, les modifications d'élément et les modifications structurelles. Les changements d'élément surviennent lorsqu'un seul élément a ses données mises à jour sans qu'aucun changement de position ne se soit produit. Les modifications structurelles surviennent lorsque des éléments sont insérés, supprimés ou déplacés dans l'ensemble de données.

Ceci est tiré de la page susmentionnée,

Si vous écrivez un adaptateur, il sera toujours plus efficace d'utiliser les événements de changement plus spécifiques si vous le pouvez. Faites appel à notifyDataSetChanged () en dernier recours.

Donc, juste pour clarifier, utilisez notifyDataSetChanged() en en dernier recours , et demandez-vous plutôt si vous pouvez appliquer l'une de ces méthodes à la place, et si vous pouvez l'utiliser à la place:

notifyItemChanged(int)
notifyItemInserted(int)
notifyItemRemoved(int)
notifyItemRangeChanged(int, int)
notifyItemRangeInserted(int, int)
notifyItemRangeRemoved(int, int)

ce qui a du sens parce que notifyDataSetChanged() va pratiquement essayer de tout redessiner en fonction des données et de ne pas faire d'hypothèses antérieures, tandis que les autres méthodes ne feront que rechercher des modifications. Cela signifie que l’adaptateur doit faire beaucoup plus de travail qui n’est pas nécessaire. C'est ce que fait notifyDataSetChanged():

Cet événement ne précise pas ce qui a changé dans le jeu de données, ce qui oblige tout observateur à supposer que tous les éléments et la structure existants risquent de ne plus être valides. Les responsables de la mise en page seront obligés de relier complètement et de relayer toutes les vues visibles.

Il est également judicieux d’utiliser l’approche incrémentielle ou par intervalle, car vous modifiez le texte, vous devez aller chercher chaque nouveau texte et vous devez alors indiquer à l’adaptateur que vous l’avez modifié. Maintenant, si vous faites un clic sur un bouton et obtenez toutes les nouvelles valeurs de texte, et créez une nouvelle liste ou quelque chose, appelez heavy notifyDataSetChanged().

63
napkinsterror

J'appellerais certainement notifyDataSetChanged() si tous les éléments de données n'étaient plus valides. Lorsque vous appelez notifyItemChanged(mPos), cela équivaut à un appel à notifyItemRangeChanged(mPos, 1), et chaque fois que vous l'appelez, requestLayout() est également appelé. Par contre, lorsque vous appelez notifyDataSetChanged() ou notifyItemRangeChanged(0, mList.size()), un seul appel à requestLayout() est lancé.

Votre question devrait maintenant être, quoi de mieux, un appel à notifyDataSetChanged() ou notifyItemRangeChanged(0, mList.size())? Pour celui-là je n'ai pas de réponse.

13
Ari

J'ai remarqué que notifyItemChanged(mPos) déclenche onBindVieHolder pour la position correspondante même si elle n'est pas visible pour le moment.

Pour moi, l'appeler dans une boucle pour tous les éléments était plus coûteux que notifyDatasetChanged, qui ne redessine que les éléments visibles.

Alors soyez prudent avec les grands ensembles de données.

5