Android Recyclerview vs ListView mit Viewholder


148

Ich bin kürzlich auf das Android gestoßen, RecyclerViewdas mit Android 5.0 veröffentlicht wurde, und es scheint, dass RecyclerViewes sich nur um ein gekapseltes traditionelles ListViewAndroid-Muster handelt, das die Wiederverwendung der Ansicht fördert, anstatt sie jedes Mal zu erstellen.

Was sind die anderen Vorteile der Verwendung RecyclerView? Wenn beide den gleichen Leistungseffekt haben, warum sollte man RecyclerView bevorzugen?

Bearbeiten

Ich fand heraus, dass die Leute ähnliche Fragen gestellt haben und die Antworten nicht schlüssig sind, und fügte sie hier zur Aufzeichnung hinzu.

Recyclerview vs Listview

Sollten wir RecyclerView verwenden, um ListView zu ersetzen?

Warum hat RecyclerView nicht onItemClickListener ()? und wie unterscheidet sich RecyclerView von Listview?


4
Weil das RecyclerViewmit einer viel besseren API viel schneller und vielseitiger ist. Dinge wie das Animieren des Hinzufügens oder Entfernens von Elementen sind bereits in der implementiert, RecyclerViewohne dass Sie etwas tun müssen. Keine Frage, wirf deinen ListViewin den Mülleimer, der RecyclerViewist hier, um die Show zu stehlen.
Xaver Kapeller

4
Sie können einen Layout-Manager einer RecyclerView zuordnen, sodass diese nicht auf vertikal scrollende Listen beschränkt sind. Dies ist eine recht leistungsstarke Zusatzfunktionalität.
Alan

@Alan - Was meinst du mit "nicht auf vertikal scrollende Listen beschränkt"? Wollen Sie damit sagen, dass die Recycle-Ansicht auch als "Platzhalter" für Gridviews und ListViews fungieren kann?
Mushtaq Jameel

@XaverKapeller - Es wäre großartig, wenn Sie die Unterschiede zwischen den beiden auflisten und die Frage beantworten könnten, anstatt einen Kommentar abzugeben, damit es mir und den anderen in Zukunft helfen könnte, die sich über das Gleiche wundern könnten.
Mushtaq Jameel

@Alan - Könnten Sie ein bisschen detailliert angeben, was Sie gemeint haben, und die Frage beantworten, anstatt einen Kommentar abzugeben? Vielen Dank, dass Sie sich die Zeit genommen haben
Mushtaq Jameel

Antworten:


289

Mit dem Aufkommen von Android Lollipop hat das RecyclerView offiziell seinen Weg gefunden. Das RecyclerView ist viel leistungsfähiger, flexibler und eine wesentliche Verbesserung gegenüber ListView . Ich werde versuchen, Ihnen einen detaillierten Einblick zu geben.

1) ViewHolder-Muster

In einer ListView wurde empfohlen, das ViewHolder-Muster zu verwenden, aber es war nie ein Zwang. Bei RecyclerView ist dies mithilfe der RecyclerView.ViewHolder- Klasse obligatorisch . Dies ist einer der Hauptunterschiede zwischen ListView und RecyclerView.

Dies macht die Dinge in RecyclerView etwas komplexer, aber viele Probleme, mit denen wir in ListView konfrontiert waren, werden effizient gelöst.

2) LayoutManager

Dies ist eine weitere massive Verbesserung von RecyclerView. In einer ListView ist nur die vertikale ListView verfügbar. Es gibt keine offizielle Möglichkeit, eine horizontale ListView zu implementieren.

Mit einem RecyclerView können wir jetzt einen haben

i) LinearLayoutManager - unterstützt sowohl vertikale als auch horizontale Listen,

ii) StaggeredLayoutManager - der Pinterest wie gestaffelte Listen unterstützt,

iii) GridLayoutManager - unterstützt die Anzeige von Gittern in Galerie-Apps.

Und das Beste ist, dass wir all dies dynamisch tun können, wie wir wollen.

3) Item Animator

ListViews unterstützen keine guten Animationen, aber die RecyclerView bringt eine ganz neue Dimension. Mit der RecyclerView.ItemAnimator- Klasse wird das Animieren der Ansichten so einfach und intuitiv.

4) Artikeldekoration

Bei ListViews war es nie einfach, Elemente wie das Hinzufügen von Rahmen oder Teilern dynamisch zu dekorieren. Im Fall von RecyclerView bietet die RecyclerView.ItemDecorator- Klasse den Entwicklern eine enorme Kontrolle, macht die Dinge jedoch etwas zeitaufwändiger und komplexer.

5) OnItemTouchListener

Das Abfangen von Elementklicks auf eine ListView war dank der AdapterView.OnItemClickListener- Oberfläche einfach . Der RecyclerView bietet seinen Entwicklern jedoch viel mehr Leistung und Kontrolle durch den RecyclerView.OnItemTouchListener (wird nicht mehr unterstützt, siehe AndroidX ), macht den Entwickler jedoch etwas komplizierter.

Mit einfachen Worten, das RecyclerView ist viel anpassbarer als das ListView und bietet seinen Entwicklern viel Kontrolle und Leistung.


34
Gute Antwort. Ein paar zusätzliche große Pluspunkte: RecyclerView bereitet die Ansicht direkt vor und hinter den sichtbaren Einträgen vor. Dies ist ideal, wenn Sie Bitmaps im Hintergrund abrufen. Die Leistung ist erheblich schneller, insbesondere wenn Sie RecyclerView.setHasFixedSize verwenden. Die alte ListView basiert auf der Prämisse, dass es keine Möglichkeit gibt, die Größe der Einträge in der Liste vorab zu berechnen oder zwischenzuspeichern, was zu wahnsinnigen Komplikationen beim Scrollen und Ausführen des Layouts führt. Es dauert eine Weile, bis Sie sich daran gewöhnt haben, aber wenn Sie es einmal getan haben, werden Sie nie mehr zurückkehren.
Robin Davies

@RobinDavies Ausgezeichneter Punkt. Vielen Dank für die Information. Es macht jedoch keinen Sinn, wenn die Größen der Artikel unterschiedlich sind.
Aritra Roy

@AritraRoy Recyclerview unterstützt nur auf Lutscher oder API 14+ (Android 4+) auch? .... wie ich las "nach Lutscher: an den meisten Orten
Animesh Mangla

2
Hey, Aritra, wenn ListView im Vergleich zu ListView auch das ViewHolder-Muster verwendet, welches wirkt effizienter? Wird RecylerView das bessere, wenn fps oder ein anderes ähnliches Kriterium verwendet? thx ~
RxRead

@RxRead: Siehe Robins Kommentar, er unterscheidet RecyclerView von ListView mit dem Muster des Ansichtsinhabers aus Gründen der Leistung.
Parag Kadam

10

Das andere Plus der Verwendung RecycleViewist die Animation. Sie kann in zwei Codezeilen ausgeführt werden

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

Das Widget ist jedoch noch roh, z. B. können Sie keine Kopf- und Fußzeilen erstellen .


5
Und Sie werden niemals in der Lage sein, Kopf- und Fußzeilen in diesem Sinne zu erstellen. Dies sind nur andere Ansichtstypen in Ihrem Adapter. Die Listenansicht schließt Ihren Adapter ein HeaderViewListAdapterund fügt im Hintergrund Header-Unterstützung hinzu. Mit RecyclerViewdir hast du die Kontrolle.
Eugen Pechanec

RecyclerView verwendet standardmäßig einen DefaultItemAnimator. Warum haben Sie dann diesen Code verwendet?
Athira Reddy

9

Okay, so ein bisschen graben und ich fand diese Edelsteine ​​aus dem Artikel von Bill Philips aufRecycleView

RecyclerView kann mehr als ListView, aber die RecyclerView-Klasse selbst hat weniger Verantwortlichkeiten als ListView. RecyclerView ist standardmäßig nicht in der Lage:

  • Positionieren Sie Elemente auf dem Bildschirm
  • Ansichten animieren
  • Behandeln Sie alle Berührungsereignisse außer dem Scrollen

All diese Dinge wurden in ListView integriert, aber RecyclerView verwendet stattdessen Collaborator-Klassen, um diese Jobs auszuführen.

Die von Ihnen erstellten ViewHolders sind ebenfalls leistungsfähiger. Sie Unterklasse RecyclerView.ViewHolder, die eine Reihe von Methoden RecyclerView verwendet. ViewHoldersSie wissen, an welche Position sie derzeit gebunden sind und welche Artikel-IDs (falls vorhanden) vorhanden sind. Dabei ViewHolder wurde zum Ritter geschlagen. Früher war es ListViews Aufgabe, die gesamte Elementansicht und ViewHoldernur kleine Teile davon festzuhalten .

Jetzt behält ViewHolder alles im ViewHolder.itemView Feld bei, das im ViewHolder-Konstruktor für Sie zugewiesen ist.


4

Mehr aus dem Artikel von Bill Phillip (lesen Sie es!), Aber ich fand es wichtig, auf Folgendes hinzuweisen.

In ListView gab es einige Unklarheiten hinsichtlich der Behandlung von Klickereignissen: Sollten die einzelnen Ansichten diese Ereignisse behandeln oder sollte die ListView sie über OnItemClickListener behandeln? In RecyclerView kann der ViewHolder jedoch eindeutig als Controller-Objekt auf Zeilenebene fungieren, das diese Art von Details verarbeitet.

Wir haben bereits gesehen, dass LayoutManager Positionierungsansichten und ItemAnimator die Animation behandelt. ViewHolder ist das letzte Element: Es ist für die Behandlung aller Ereignisse verantwortlich, die bei einem bestimmten Element auftreten, das RecyclerView anzeigt.


2

Ich habe einen ListViewmit Glide-Bildlader verwendet, der Speicherwachstum aufweist. Dann habe ich das ListViewdurch ein ersetzt RecyclerView. Es ist nicht nur schwieriger zu codieren, sondern führt auch zu einer höheren Speichernutzung als a ListView. Zumindest in meinem Projekt.

In einer anderen Aktivität habe ich eine komplexe Liste mit verwendet EditText's. In einigen von ihnen kann eine Eingabemethode variieren, auch eine TextWatcherkann angewendet werden. Wenn ich a verwenden würde ViewHolder, wie könnte ich a TextWatcherbeim Scrollen ersetzen ? Also habe ich ein ListViewohne a verwendet ViewHolderund es funktioniert.


Ich habe eine ListView ohne ViewHolder verwendet und es funktioniert. schreckliche Idee ... wie könnte ich einen TextWatcher beim Scrollen ersetzen? es ist nicht nötig, es zu ersetzen ... nur TextWacher sollte Daten nach der Wiederverwendung in einen anderen Container legen ... und es kann wirklich einfach gemacht werden
Selvin

@ Selvin, danke für deine Meinung. Jetzt kann ich das Projekt nicht bearbeiten. Es gab mehrere TextWatchers auf einem Bildschirm. Wahrscheinlich hast du recht, aber ich kann es nicht überprüfen.
CoolMind

1

Wiederverwendet Zellen beim Scrollen nach oben / unten - dies ist mit der Implementierung von View Holder im listView-Adapter möglich, war jedoch optional, während dies in RecycleView die Standardmethode zum Schreiben des Adapters ist.

Entkoppelt die Liste von ihrem Container - so können Sie Listenelemente zur Laufzeit einfach in die verschiedenen Container (linearLayout, gridLayout) einfügen, indem Sie LayoutManager festlegen.

Beispiel:

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));
  • Animiert allgemeine Listenaktionen.

  • Animationen werden entkoppelt und an delegiert ItemAnimator.

Es gibt mehr über RecyclerView, aber ich denke, diese Punkte sind die wichtigsten.

LayoutManager

i) LinearLayoutManager - unterstützt sowohl vertikale als auch horizontale Listen,

ii) StaggeredLayoutManager - der Pinterest wie gestaffelte Listen unterstützt,

iii) GridLayoutManager - unterstützt die Anzeige von Gittern in Galerie-Apps.

Und das Beste ist, dass wir all dies dynamisch tun können, wie wir wollen.


1

1. Inhaber anzeigen

In ListView war das Definieren von Ansichtsinhabern ein empfohlener Ansatz, um Referenzen für Ansichten beizubehalten. Aber es war kein Zwang. Wenn dies nicht der Fall ist, zeigt ListView veraltete Daten an. Ein weiterer großer Nachteil der Nichtverwendung von Ansichtshaltern könnte dazu führen, dass jedes Mal Ansichten anhand von IDs gefunden werden. Was zu verzögerten ListViews führte.

Dieses Problem wird in RecylerView mithilfe der RecyclerView.ViewHolder-Klasse gelöst. Dies ist einer der Hauptunterschiede in RecyclerView und ListView. Bei der Implementierung einer RecyclerView wird diese Klasse verwendet, um ein ViewHolder-Objekt zu definieren, das vom Adapter verwendet wird, um ViewHolder an eine Position zu binden. Ein weiterer Punkt, der hier zu beachten ist, ist, dass bei der Implementierung des Adapters für RecyclerView die Bereitstellung eines ViewHolder obligatorisch ist. Dies macht die Implementierung etwas komplex, löst jedoch die Probleme in ListView.

2. Layout Manager

Wenn von ListViews gesprochen wird, ist nur ein ListView-Typ verfügbar, nämlich die vertikale ListView. Sie können eine ListView mit horizontalem Bildlauf nicht implementieren. Ich weiß, dass es Möglichkeiten gibt, eine horizontale Schriftrolle zu implementieren, aber glauben Sie mir, dass sie nicht so konzipiert wurde.

Wenn wir uns jetzt Android RecyclerView und ListView ansehen, unterstützen wir auch horizontale Sammlungen. Tatsächlich unterstützt es mehrere Arten von Listen. Zur Unterstützung mehrerer Listentypen wird die RecyclerView.LayoutManager-Klasse verwendet. Dies ist etwas Neues, das ListView nicht hat. RecyclerView unterstützt drei Arten vordefinierter Layout-Manager:

LinearLayoutManager - Dies ist der am häufigsten verwendete Layout-Manager bei RecyclerView. Auf diese Weise können wir sowohl horizontale als auch vertikale Bildlauflisten erstellen. StaggeredGridLayoutManager - Mit diesem Layout-Manager können wir gestaffelte Listen erstellen. Genau wie der Pinterest-Bildschirm. GridLayoutManager - Mit diesem Layout-Manager können Raster wie in jeder Bildergalerie angezeigt werden.

3. Item Animator

Animationen in einer Liste sind eine völlig neue Dimension, die endlose Möglichkeiten bietet. In einer ListView als solche gibt es keine besonderen Bestimmungen, durch die Elemente animiert, hinzugefügt oder gelöscht werden können. Stattdessen wurde später, als sich Android weiterentwickelte, ViewPropertyAnimator von Googles Chet Haase in diesem Video-Tutorial für Animationen in ListView vorgeschlagen.

Beim Vergleich von Android RecyclerView mit ListView verfügt es über die RecyclerView.ItemAnimator-Klasse für die Verarbeitung von Animationen. Durch diese Klasse können benutzerdefinierte Animationen für das Hinzufügen, Löschen und Verschieben von Elementen definiert werden. Außerdem bietet es einen DefaultItemAnimator, falls Sie keine Anpassungen benötigen.

4. Adapter

ListView-Adapter waren einfach zu implementieren. Sie hatten eine Hauptmethode getView, bei der all die Magie passierte. Wo die Ansichten an eine Position gebunden waren. Außerdem hatten sie eine interessante Methode registerDataSetObserver, mit der man einen Beobachter direkt im Adapter einstellen kann. Diese Funktion ist auch in RecyclerView vorhanden, es wird jedoch die RecyclerView.AdapterDataObserver-Klasse verwendet. Der Vorteil von ListView besteht jedoch darin, dass drei Standardimplementierungen von Adaptern unterstützt werden:

ArrayAdapter CursorAdapter SimpleCursorAdapter Während der RecyclerView-Adapter alle Funktionen von ListView-Adaptern mit Ausnahme der integrierten Unterstützung für DB-Cursor und ArrayLists bietet. In RecyclerView.Adapter müssen wir ab sofort eine benutzerdefinierte Implementierung vornehmen, um Daten an den Adapter zu liefern. Genau wie ein BaseAdapter für ListViews. Wenn Sie mehr über die Implementierung des RecyclerView-Adapters erfahren möchten, lesen Sie bitte das Beispiel für Android RecyclerView.

5. Benachrichtigung über Datenänderungen

Wenn Sie mit einer ListView arbeiten und der Datensatz geändert wird, müssen Sie die notifyDataSetChanged-Methode des zugrunde liegenden Adapters aufrufen, um die Daten zu aktualisieren. Oder setzen Sie die setNotifyOnChange-Methode auf true, falls Sie die notifyDataSetChanged-Methode automatisch aufrufen möchten. Aber in beiden Fällen steht das Ergebnis ganz oben auf der Liste. Grundsätzlich werden die Ansichten der Liste aktualisiert.

Im Gegenteil, in einem RecyclerView-Adapter gibt es Methoden, um die Änderung entsprechend zu benachrichtigen, wenn sich ein einzelnes Element oder eine Reihe von Elementen geändert hat. Dies sind notifyItemChanged bzw. notifyItemRangeChanged und viele weitere wie:

notifyItemInsterted notifyItemMoved notifyItemRangeInsterted notifyItemRangeRemoved Und natürlich hat es die ursprüngliche Methode zum Aktualisieren der gesamten Liste, dh notifyDataSetChanged, die benachrichtigt, dass der angepasste gesamte Datensatz geändert wurde.

6. Artikeldekoration

Um benutzerdefinierte Teiler in einer ListView anzuzeigen, hätte man diese Parameter leicht in die ListView-XML einfügen können:

XHTML android: divider = "@ android: color / transparent" android: dividerHeight = "5dp" 1 2 android: divider = "@ android: color / transparent" android: dividerHeight = "5dp" Der interessante Teil von Android RecyclerView ist, dass Ab sofort wird standardmäßig keine Trennlinie zwischen Elementen angezeigt. Obwohl die Leute bei Google dies absichtlich für die Anpassung ausgelassen haben müssen. Dies erhöht jedoch den Aufwand für einen Entwickler erheblich. Wenn Sie einen Teiler zwischen Elementen hinzufügen möchten, müssen Sie möglicherweise eine benutzerdefinierte Implementierung mithilfe der RecyclerView.ItemDecoration-Klasse durchführen.

Oder Sie können einen Hack anwenden, indem Sie diese Datei aus offiziellen Beispielen verwenden: DividerItemDecoration.java

7. OnItemTouchListener

Listenansichten hatten früher eine einfache Implementierung zur Erkennung von Klicks, dh mithilfe der AdapterView.OnItemClickListener-Schnittstelle.

Auf der anderen Seite wird die RecyclerView.OnItemTouchListener-Oberfläche verwendet, um Berührungsereignisse in Android RecyclerView zu erkennen. Dies erschwert die Implementierung ein wenig, bietet dem Entwickler jedoch eine bessere Kontrolle über das Abfangen von Berührungsereignissen. In der offiziellen Dokumentation heißt es, dass es für gestische Manipulationen nützlich sein kann, da es ein Berührungsereignis abfängt, bevor es an RecyclerView übermittelt wird.


1

RecyclerView wurde als ListView-Verbesserung erstellt. Ja, Sie können eine angehängte Liste mit dem ListView-Steuerelement erstellen. Die Verwendung von RecyclerView ist jedoch einfacher, da:

  1. Wiederverwenden von Zellen beim Scrollen nach oben / unten : Dies ist mit der Implementierung von View Holder im ListView-Adapter möglich, war jedoch optional, während dies in RecycleView die Standardmethode zum Schreiben des Adapters ist.

  2. Entkoppelt die Liste von ihrem Container : So können Sie Listenelemente zur Laufzeit einfach in die verschiedenen Container (linearLayout, gridLayout) einfügen, indem Sie LayoutManager festlegen.

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

  1. Animiert allgemeine Listenaktionen : Animationen werden entkoppelt und an ItemAnimator delegiert. Es gibt mehr über RecyclerView, aber ich denke, diese Punkte sind die wichtigsten.

Zusammenfassend lässt sich sagen, dass RecyclerView eine flexiblere Steuerung für den Umgang mit "Listendaten" ist, die den Mustern der Delegation von Bedenken folgt und nur eine Aufgabe für sich lässt - das Recycling von Elementen.


0

Wenn Sie RecycleView verwenden, benötigen Sie zunächst mehr Aufwand für die Einrichtung. Sie müssen mehr Zeit einplanen, um einfache Elemente per Mausklick, Rahmen, Berührungsereignis und andere einfache Dinge einzurichten. Aber das Endprodukt wird perfekt sein.

Die Entscheidung liegt also bei Ihnen. Ich schlage vor, wenn Sie eine einfache App wie das Laden von Telefonbüchern entwerfen, bei der ein einfacher Klick auf ein Element ausreicht, können Sie die Listenansicht implementieren. Aber wenn Sie wie eine Social-Media-Homepage mit unbegrenztem Bildlauf gestalten. Mehrere verschiedene Dekorationen zwischen den Artikeln, viel Kontrolle über einzelne Artikel als die Recycling-Ansicht.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.