web-dev-qa-db-fra.com

Android Recyclerview vs ListView avec Viewholder

Je suis récemment tombé sur le Android RecycleView qui a été publié avec Android 5.0 et il semble que RecycleView soit simplement un ListView encapsulé traditionnel avec le Le motif ViewHolder qui y est incorporé encourage la réutilisation de la vue plutôt que sa création à chaque fois.

Quels sont les autres avantages de RecycleView? Si les deux ont le même effet en termes de performances, pourquoi voudrait-on utiliser RecycleView`?

Modifier

J'ai constaté que des personnes ont posé des questions similaires et que les réponses ne sont pas concluantes, en les ajoutant ici pour la tenue des dossiers.

Recyclerview vs Listview

Devrions-nous utiliser RecyclerView pour remplacer ListView?

Pourquoi RecyclerView n'a-t-il pas onItemClickListener ()? Et en quoi RecyclerView est différent de Listview?

138
Mushtaq Jameel

Avec l'avènement de Android Lollipop, le RecyclerView a officiellement fait son chemin. RecyclerView est beaucoup plus puissant , flexible et constitue une amélioration majeure par rapport à ListView . Je vais essayer de vous donner un aperçu détaillé à ce sujet.

1) Modèle ViewHolder

Dans un ListView, il était recommandé d'utiliser le modèle ViewHolder mais ce n'était jamais une contrainte. Dans le cas de RecyclerView, ceci est obligatoire en utilisant la classe RecyclerView.ViewHolder . C'est l'une des différences majeures entre ListView et RecyclerView.

Cela rend les choses un peu plus complexes dans RecyclerView mais beaucoup de problèmes que nous avons rencontrés dans ListView sont résolus efficacement.

2) LayoutManager

Ceci est une autre amélioration massive apportée au RecyclerView. Dans un ListView, le seul type de vue disponible est le ListView vertical. Il n’existe aucun moyen officiel d’implémenter un ListView horizontal.

Maintenant, en utilisant un RecyclerView, nous pouvons avoir un

i) LinearLayoutManager - qui prend en charge les listes verticales et horizontales,

ii) StaggeredLayoutManager - qui prend en charge Pinterest comme des listes décalées,

iii) GridLayoutManager - qui prend en charge l'affichage de grilles telles qu'elles apparaissent dans les applications Gallery.

Et la meilleure chose à faire est que nous pouvons faire tout cela dynamiquement comme nous le voulons.

3) Item Animator

ListViews ne prend pas en charge de bonnes animations, mais RecyclerView lui apporte une toute nouvelle dimension. En utilisant la classe RecyclerView.ItemAnimator , l'animation des vues devient tellement simple et intuitive.

4) Décoration de l'objet

Dans le cas de ListViews, la décoration dynamique d'éléments tels que l'ajout de bordures ou de séparateurs n'a jamais été aussi simple. Mais dans le cas de RecyclerView, la classe RecyclerView.ItemDecorator donne un contrôle énorme aux développeurs, mais rend les choses un peu plus longues et complexes.

5) OnItemTouchListener

Intercepter les clics d’éléments sur un ListView était simple, grâce à son interface AdapterView.OnItemClickListener . Mais le RecyclerView donne beaucoup plus de puissance et de contrôle à ses développeurs par le RecyclerView.OnItemTouchListener mais cela complique un peu les choses pour le développeur.

En termes simples, le RecyclerView est beaucoup plus personnalisable que le ListView et donne beaucoup de contrôle et de puissance à ses développeurs.

277
Aritra Roy

L'autre avantage d'utiliser RecycleView est une animation, cela peut être fait en deux lignes de code

RecyclerView.ItemAnimator itemAnimator = new DefaultItemAnimator();
        recyclerView.setItemAnimator(itemAnimator);

Mais le widget est toujours brut, par exemple, vous ne pouvez pas créer en-tête et pied de page.

9
Etun

Okay donc si peu de creuser et j'ai trouvé ces gemmes de Bill Philips article sur RecycleView

RecyclerView peut faire plus que ListView, mais la classe RecyclerView elle-même a moins de responsabilités que ListView. Hors de la boîte, RecyclerView ne:

  • Articles de position sur l'écran
  • Animer des vues
  • Gérer tous les événements tactiles en dehors du défilement

Tout cela a été intégré à ListView, mais RecyclerView utilise des classes de collaborateurs pour effectuer ces tâches à la place.

Les ViewHolders que vous créez sont également plus costauds. Ils sous-classe RecyclerView.ViewHolder, qui a un tas de méthodes RecyclerView utilise. ViewHolders savoir à quelle position ils sont actuellement liés, ainsi que les ID d’élément (si vous en avez). Dans le processus, ViewHolder a été anobli. Auparavant, c'était le travail de ListView de conserver toute la vue de l'élément, et ViewHolder uniquement de petits morceaux de celle-ci.

Désormais, ViewHolder conserve l’ensemble de ces informations dans le champ ViewHolder.itemView, qui est affecté dans le constructeur de ViewHolder.

8
Mushtaq Jameel

Plus d'articles de Bill Phillip's article (allez le lire!) Mais j'ai pensé qu'il était important de souligner ce qui suit.

Dans ListView, il y avait une certaine ambiguïté sur la façon de gérer les événements de clic: les vues individuelles devaient-elles gérer ces événements ou la vue de liste devait-elle les gérer via OnItemClickListener? Dans RecyclerView, cependant, ViewHolder est clairement placé pour agir en tant qu'objet de contrôleur de niveau ligne qui gère ce type de détails.

Nous avons vu précédemment que LayoutManager gérait les vues de positionnement et ItemAnimator traitait de leur animation. ViewHolder est la dernière pièce: il est responsable de la gestion des événements qui se produisent sur un élément spécifique affiché par RecyclerView.

4
Jaison Brooks

J'ai utilisé un ListView avec le chargeur d'images Glide, qui présente une croissance de la mémoire. Puis j'ai remplacé le ListView par un RecyclerView. Il est non seulement plus difficile à coder, mais entraîne également une utilisation plus importante de la mémoire qu'un ListView. Du moins dans mon projet.

Dans une autre activité, j'ai utilisé une liste complexe avec EditText's. Dans certains cas, une méthode de saisie peut varier, mais un TextWatcher peut également être appliqué. Si j’utilisais un ViewHolder, comment pourrais-je remplacer un TextWatcher lors du défilement? Donc, j'ai utilisé un ListView sans un ViewHolder, et ça marche.

2
CoolMind

Réutilise les cellules en faisant défiler vers le haut/bas - Ceci est possible avec l’implémentation de View Holder dans l’adaptateur listView, mais c’était une option, alors que dans RecycleView, c’est la méthode par défaut pour écrire l’adaptateur.

Découple la liste de son conteneur - afin que vous puissiez facilement insérer des éléments de la liste au moment de l'exécution dans les différents conteneurs (linearLayout, gridLayout) en définissant LayoutManager.

Exemple:

mRecyclerView = (RecyclerView) findViewById(R.id.recycler_view);
mRecyclerView.setLayoutManager(new LinearLayoutManager(this));
//or
mRecyclerView.setLayoutManager(new GridLayoutManager(this, 2));
mRecyclerView.setLayoutManager(new GridLayoutManager(this, 3));
  • Anime des actions de liste communes.

  • Les animations sont découplées et déléguées à ItemAnimator.

Il y a plus sur RecyclerView, mais je pense que ces points sont les principaux.

LayoutManager

i) LinearLayoutManager - qui prend en charge les listes verticales et horizontales,

ii) StaggeredLayoutManager - qui prend en charge Pinterest comme des listes décalées,

iii) GridLayoutManager - qui prend en charge l'affichage de grilles telles qu'elles apparaissent dans les applications de la galerie.

Et la meilleure chose à faire est que nous pouvons faire tout cela dynamiquement comme nous le voulons.

1
Keshav Gera

RecyclerView a été créé en tant qu'amélioration ListView. Vous pouvez donc créer une liste attachée avec un contrôle ListView, mais utiliser RecyclerView est plus simple car il:

  1. Réutilise les cellules en faisant défiler vers le haut/bas: Ceci est possible avec l’implémentation de View Holder dans l’adaptateur ListView, mais c’était une option, alors que dans RecycleView, c’est la méthode par défaut pour écrire l’adaptateur.

  2. Découple la liste de son conteneur: vous pouvez donc facilement insérer des éléments de la liste au moment de l'exécution dans les différents conteneurs (linearLayout, gridLayout) en définissant LayoutManager.

mRecyclerView = (RecyclerView) findViewById (R.id.my_recycler_view); mRecyclerView.setLayoutManager (new LinearLayoutManager (this)); mRecyclerView.setLayoutManager (nouveau GridLayoutManager (this, 2));

  1. Anime des actions de liste communes: Les animations sont découplées et déléguées à ItemAnimator. Il y a plus sur RecyclerView, mais je pense que ces points sont les principaux.

Donc, pour conclure, RecyclerView est un contrôle plus souple pour le traitement des "données de liste" qui suit des schémas de délégation de préoccupations et ne laisse pour lui-même qu’une tâche: recycler des éléments.

0
farzin borujerdi

1. Détenteurs de vue

Dans ListView, la définition des détenteurs de vues était une approche suggérée pour conserver les références des vues. Mais ce n'était pas une contrainte. Bien que cela n’ait pas été le cas, ListView a utilisé des données obsolètes. Un autre inconvénient majeur de ne pas utiliser les détenteurs de vues pourrait conduire à une lourde opération de recherche de vues par identifiants à chaque fois. Ce qui a abouti à des ListViews tardifs.

Ce problème est résolu dans RecylerView par l’utilisation de la classe RecyclerView.ViewHolder. C'est l'une des différences majeures entre RecyclerView et ListView. Lors de l'implémentation de RecyclerView, cette classe est utilisée pour définir un objet ViewHolder utilisé par l'adaptateur pour lier ViewHolder à une position. Un autre point à noter ici est que lors de la mise en œuvre de l'adaptateur pour RecyclerView, la fourniture d'un ViewHolder est obligatoire. Cela rend la mise en œuvre un peu complexe, mais résout les problèmes rencontrés dans ListView.

2. Gestionnaire de mise en page

En parlant de ListViews, un seul type de ListView est disponible, à savoir le ListView vertical. Vous ne pouvez pas implémenter un ListView avec défilement horizontal. Je sais qu'il existe des moyens d'implémenter un parchemin horizontal, mais croyez-moi, il n'a pas été conçu pour fonctionner de cette manière.

Mais maintenant, lorsque nous regardons Android RecyclerView contre ListView, nous pouvons également prendre en charge les collections horizontales. En fait, il prend en charge plusieurs types de listes. Pour prendre en charge plusieurs types de listes, il utilise la classe RecyclerView.LayoutManager. Ceci est quelque chose de nouveau que ListView n'a pas. RecyclerView prend en charge trois types de gestionnaires de disposition prédéfinis:

LinearLayoutManager - C'est le gestionnaire de disposition le plus couramment utilisé dans le cas de RecyclerView. Grâce à cela, nous pouvons créer des listes de défilement horizontales et verticales. StaggeredGridLayoutManager - Ce gestionnaire de dispositions permet de créer des listes échelonnées. Tout comme l'écran Pinterest. GridLayoutManager– Ce gestionnaire de disposition peut être utilisé pour afficher des grilles, comme n'importe quelle galerie d'images.

. Item Animator

Les animations dans une liste constituent une toute nouvelle dimension, avec des possibilités infinies. Dans un ListView, en tant que tel, il n’existe aucune disposition spéciale permettant d’animer, d’ajouter ou de supprimer des éléments. Par la suite, sous le nom de Android, évolué, ViewPropertyAnimator a été suggéré par Google Chet Haase dans ce didacticiel vidéo pour les animations de ListView.

D'autre part, en comparant Android RecyclerView contre ListView, il possède la classe RecyclerView.ItemAnimator pour la gestion des animations. Cette classe permet de définir des animations personnalisées pour les événements d’ajout, de suppression et de déplacement d’éléments. En outre, il fournit un DefaultItemAnimator, au cas où vous n’auriez besoin d’aucune personnalisation.

4. Adaptateur

Les adaptateurs ListView étaient simples à mettre en œuvre. Ils avaient une méthode principale getView où toute la magie se produisait. Où les vues étaient liées à une position. En outre, ils avaient une méthode intéressante, registerDataSetObserver, dans laquelle on peut définir un observateur directement dans l'adaptateur. Cette fonctionnalité est également présente dans RecyclerView, mais la classe RecyclerView.AdapterDataObserver est utilisée pour cela. Mais le point en faveur de ListView est qu’il prend en charge trois implémentations par défaut d’adaptateurs:

ArrayAdapter CursorAdapter SimpleCursorAdapter Considérant que l’adaptateur RecyclerView possède toutes les fonctionnalités des adaptateurs ListView, à l’exception de la prise en charge intégrée des curseurs de base de données et ArrayLists. Dans RecyclerView.Adapter à partir de maintenant, nous devons créer une implémentation personnalisée pour fournir des données à l'adaptateur. Tout comme le fait un adaptateur de base pour ListViews. Toutefois, si vous souhaitez en savoir plus sur la mise en œuvre de l’adaptateur RecyclerView, veuillez vous reporter à Android Exemple de RecyclerView.

5. Notification de modification de données

Lorsque vous utilisez un ListView, si le jeu de données est modifié, vous devez appeler la méthode notifyDataSetChanged de l'adaptateur sous-jacent pour actualiser les données. Vous pouvez également définir la méthode setNotifyOnChange sur true si vous souhaitez appeler la méthode notifyDataSetChanged automatiquement. Mais dans les deux cas, le résultat est très lourd sur la liste. Fondamentalement, il actualise les vues de la liste.

Mais au contraire, dans un adaptateur RecyclerView, si un seul élément ou une plage d’éléments ont été modifiés, il existe des méthodes pour notifier le changement en conséquence. Ceux-ci sont respectivement notifyItemChanged et notifyItemRangeChanged et beaucoup d'autres comme:

notifyItemInsterted notifyItemMoved notifyItemRangeInsterted notifyItemRangeRemoved Et bien sûr, il a la méthode originale pour actualiser la liste entière, à savoir notifyDataSetChanged, qui informe que tout le jeu de données adapté a été modifié.

6. Articles de décoration

Pour afficher des séparateurs personnalisés dans un ListView, on aurait pu facilement ajouter ces paramètres dans le XML ListView:

XHTML Android: divider = "@ Android: couleur/transparent" Android: dividerHeight = "5dp" 1 2 Android: diviseur = "@ Android: couleur/transparent" Android: dividerHeight = "5dp" La partie intéressante à propos de Android RecyclerView est que, à partir de maintenant, il ne montre pas de division entre les éléments par défaut. Bien que les gars de Google aient dû laisser cela de côté pour la personnalisation, intentionnellement. Mais cela augmente considérablement les efforts du développeur. Si vous souhaitez ajouter un séparateur entre les éléments, vous devrez peut-être effectuer une implémentation personnalisée à l'aide de la classe RecyclerView.ItemDecoration.

Ou vous pouvez appliquer un hack en utilisant ce fichier à partir d'échantillons officiels: DividerItemDecoration.Java

7. OnItemTouchListener

Les vues en liste utilisaient une implémentation simple pour la détection des clics, c’est-à-dire en utilisant l’interface AdapterView.OnItemClickListener.

D'autre part, l'interface RecyclerView.OnItemTouchListener est utilisée pour détecter les événements tactiles dans Android RecyclerView. Cela complique un peu la mise en oeuvre, mais cela donne un plus grand contrôle au développeur pour intercepter les événements tactiles. Selon la documentation officielle, cela peut être utile pour les manipulations gestuelles car il intercepte un événement tactile avant qu'il ne soit transmis à RecyclerView.

0
Raviraj Desai