Ce qui est mieux? notifyDataSetChanged ou notifyItemChanged en boucle?

J’ai donc une activité avec RecyclerView et je veux changer TextView de chaque élément dans RecyclerView en appuyant sur le bouton qui a onClickListener() dans l’activité.

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

  1. Utilisez les notifyDataSetChanged .
  2. Utiliser une boucle avec une condition comme int i est inférieure à List.size()notifyItemChanged serait appelé plusieurs fois.

Dans les deux cas, je crée une variable booléenne dans RecyclerView Adapter, utilisée par onBindViewHolder pour savoir comment mettre à jour un élément. Par défaut, elle est fausse et après un clic sur le bouton, elle devient vraie, de sorte que onBindViewHolder met à jour l’élément de manière différente.

Je voudrais également savoir si cette approche convient à tous.

Si vous mettez simplement à jour une partie de la vue, utilisez le notifyItemRangeChanged() ou notifyItemChanged() au lieu de notifiyDataSetChanged() . La différence concerne les changements structurels et les changements d’ éléments . Ceci est sur la documentation des développeurs Android RecyclerView.Adapter trouvés ici .

Voici un autre point sur les différences entre les deux types de changements:

Il existe deux classes différentes d’événements de modification de données, de modifications d’éléments et de modifications structurelles. Les modifications apscopes à un article se produisent lorsqu’un élément unique a ses données mises à jour, mais aucun changement de position n’a eu lieu. Les modifications structurelles concernent les éléments insérés, supprimés ou déplacés dans l’dataset.

Ceci est tiré de cette page,

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

Donc, pour clarifier, utilisez notifyDataSetChanged() en dernier recours et demandez-vous plutôt si vous pouvez préformer 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 est logique car notifyDataSetChanged() va à peu près tout essayer de tout redessiner sur la base des données et ne pas faire d’hypothèses précédentes, alors que les autres méthodes vont simplement chercher les modifications. Cela signifie que l’adaptateur doit faire beaucoup plus de travail que nécessaire. Voici ce que notifyDataSetChanged() fait:

Cet événement ne spécifie pas ce qui a changé dans l’dataset, ce qui oblige les observateurs à supposer que tous les éléments et structures existants ne sont plus valides. Les LayoutManagers seront obligés de se reconnecter complètement et de relayer toutes les vues visibles.

Cela a également un sens d’utiliser l’approche incrémentielle ou de plage, car vous modifiez le texte, vous devez aller chercher chaque nouveau texte et lorsque vous faites cela, vous devriez dire à l’adaptateur que vous 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, alors appelez heavy notifyDataSetChanged() .

J’appellerais certainement notifyDataSetChanged() si tous les éléments de données ne sont plus valides. Lorsque vous appelez notifyItemChanged(mPos) , cela équivaut à un appel à notifyItemRangeChanged(mPos, 1) et à chaque appel, requestLayout() est également appelé. D’un autre côté, lorsque vous appelez notifyDataSetChanged() ou notifyItemRangeChanged(0, mList.size()) , il n’y a qu’un seul appel à requestLayout() .

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.

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

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

Soyez donc prudent avec les grands ensembles de données.