Dynamische Listen mit RecyclerView erstellen Teil von Android Jetpack
Mit RecyclerView können große Datenmengen einfach und effizient dargestellt werden. Sie stellen die Daten bereit und legen fest, wie die einzelnen Artikel aussehen. Die RecyclerView-Bibliothek erstellt die Elemente dann dynamisch, wenn sie benötigt werden.
Wie der Name schon sagt, werden diese einzelnen Elemente von RecyclerView recycelt. Wenn ein Element aus dem Bildschirm scrollt, löscht RecyclerView seine Ansicht nicht. Stattdessen verwendet RecyclerView die Ansicht für neue Elemente, die auf dem Bildschirm gescrollt wurden. RecyclerView verbessert die Leistung und die Reaktionsfähigkeit deiner App und reduziert den Energieverbrauch.
Schlüsselklassen
Mehrere Klassen arbeiten zusammen, um Ihre dynamische Liste zu erstellen.
RecyclerView
ist derViewGroup
, der die Ansichten enthält, die Ihren Daten entsprechen. Da es sich um eine Ansicht selbst handelt, fügen SieRecyclerView
wie jedes andere UI-Element zu Ihrem Layout hinzu.Jedes einzelne Element in der Liste wird durch ein View-holder-Objekt definiert. Wenn der Ansichtsinhaber erstellt wird, sind ihm keine Daten zugeordnet. Nachdem der Ansichtsinhaber erstellt wurde, verbindet der
RecyclerView
ihn an seine Daten. Um den Inhaber der Datenansicht zu definieren, erweitern SieRecyclerView.ViewHolder
.Der
RecyclerView
fordert Ansichten an und verknüpft sie mit ihren Daten. Dazu ruft sie Methoden im Adapter auf. Zum Definieren des Adapters erweitern SieRecyclerView.Adapter
.Im Layout-Manager werden die einzelnen Elemente in der Liste angeordnet. Sie können einen der Layout-Manager der RecyclerView-Bibliothek verwenden oder einen eigenen erstellen. Layout-Manager basieren alle auf der abstrakten
LayoutManager
-Klasse der Bibliothek.
Wie alle Teile zusammenpassen, sehen Sie in der RecyclerView-Beispiel-App (Kotlin) bzw. der RecyclerView-Beispiel-App (Java).
Schritte zur Implementierung von RecyclerView
Wenn Sie RecyclerView verwenden, müssen Sie einige Schritte ausführen, die in den folgenden Abschnitten ausführlich erläutert werden.
Legen Sie fest, wie die Liste oder das Raster aussehen soll. Normalerweise können Sie einen der Standard-Layout-Manager der RecyclerView-Bibliothek verwenden.
Legen Sie fest, wie jedes Element in der Liste aussieht und sich verhält. Erweitern Sie auf der Grundlage dieses Designs die
ViewHolder
-Klasse. Ihre Version vonViewHolder
bietet alle Funktionen für Listenelemente. Der Inhaber der Datenansicht ist ein Wrapper um einView
und diese Ansicht wird vonRecyclerView
verwaltet.Definieren Sie die
Adapter
, die Ihre Daten denViewHolder
-Datenansichten zuordnet.
Außerdem gibt es erweiterte Anpassungsoptionen, mit denen Sie RecyclerView genau an Ihre Anforderungen anpassen können.
Layout planen
Die Elemente in RecyclerView sind nach einer LayoutManager
-Klasse angeordnet. Die RecyclerView-Bibliothek bietet drei Layout-Manager für die gängigsten Layout-Situationen:
- Mit
LinearLayoutManager
werden die Elemente in einer eindimensionalen Liste angeordnet. - Mit
GridLayoutManager
werden die Elemente in einem zweidimensionalen Raster angeordnet:- Wenn das Raster vertikal angeordnet ist, versucht
GridLayoutManager
, alle Elemente in jeder Zeile dieselbe Breite und Höhe zu haben. Unterschiedliche Zeilen können jedoch unterschiedliche Höhen haben. - Wenn das Raster horizontal angeordnet ist, versucht
GridLayoutManager
, alle Elemente in jeder Spalte gleich breit und hoch zu gestalten. Unterschiedliche Spalten können jedoch unterschiedliche Breiten haben.
- Wenn das Raster vertikal angeordnet ist, versucht
StaggeredGridLayoutManager
ist mitGridLayoutManager
vergleichbar. Es ist jedoch nicht erforderlich, dass Elemente in einer Zeile dieselbe Höhe (bei vertikalen Rastern) oder Elemente in derselben Spalte (bei horizontalen Rastern) dieselbe Breite haben. Das hat zur Folge, dass die Elemente in einer Zeile oder Spalte am Ende zueinander verschoben sein können.
Sie müssen auch das Layout der einzelnen Elemente entwerfen. Sie benötigen dieses Layout, wenn Sie den Ansichtshalter entwerfen, wie im nächsten Abschnitt beschrieben.
Adapter und Halterung für die Ansicht implementieren
Nachdem Sie das Layout festgelegt haben, müssen Sie Adapter
und ViewHolder
implementieren. Diese beiden Klassen definieren zusammen, wie Ihre Daten angezeigt werden. Das ViewHolder
ist ein Wrapper um ein View
-Element, das das Layout für ein einzelnes Element in der Liste enthält. Das Adapter
erstellt nach Bedarf ViewHolder
-Objekte und legt auch die Daten für diese Ansichten fest. Das Verknüpfen von Ansichten mit ihren Daten wird als Bindung bezeichnet.
Beim Definieren des Adapters werden drei wichtige Methoden überschrieben:
onCreateViewHolder()
:RecyclerView
ruft diese Methode immer dann auf, wenn eine neueViewHolder
erstellt werden muss. Die Methode erstellt und initialisiert dasViewHolder
und die zugehörigeView
, füllt aber nicht den Inhalt der Ansicht aus, da dasViewHolder
noch nicht an bestimmte Daten gebunden wurde.onBindViewHolder()
:RecyclerView
ruft diese Methode auf, um eineViewHolder
mit Daten zu verknüpfen. Die Methode ruft die entsprechenden Daten ab und füllt damit das Layout des Ansichtsinhabers aus. Wenn beispielsweiseRecyclerView
eine Liste mit Namen anzeigt, findet die Methode möglicherweise den entsprechenden Namen in der Liste und füllt dasTextView
-Widget des Inhabers aus.getItemCount()
:RecyclerView
ruft diese Methode auf, um die Größe des Datasets abzurufen. In einer Adressbuchanwendung kann dies beispielsweise die Gesamtzahl der Adressen sein. RecyclerView verwendet dies, um festzustellen, wann keine weiteren Elemente angezeigt werden können.
Hier ist ein typisches Beispiel für einen einfachen Adapter mit einem verschachtelten ViewHolder
, das eine Liste von Daten anzeigt. In diesem Fall zeigt die RecyclerView eine einfache Liste von Textelementen an. An den Adapter wird ein String-Array übergeben, das den Text für die ViewHolder
-Elemente enthält.
Kotlin
class CustomAdapter(private val dataSet: Array<String>) : RecyclerView.Adapter<CustomAdapter.ViewHolder>() { /** * Provide a reference to the type of views that you are using * (custom ViewHolder) */ class ViewHolder(view: View) : RecyclerView.ViewHolder(view) { val textView: TextView init { // Define click listener for the ViewHolder's View textView = view.findViewById(R.id.textView) } } // Create new views (invoked by the layout manager) override fun onCreateViewHolder(viewGroup: ViewGroup, viewType: Int): ViewHolder { // Create a new view, which defines the UI of the list item val view = LayoutInflater.from(viewGroup.context) .inflate(R.layout.text_row_item, viewGroup, false) return ViewHolder(view) } // Replace the contents of a view (invoked by the layout manager) override fun onBindViewHolder(viewHolder: ViewHolder, position: Int) { // Get element from your dataset at this position and replace the // contents of the view with that element viewHolder.textView.text = dataSet[position] } // Return the size of your dataset (invoked by the layout manager) override fun getItemCount() = dataSet.size }
Java
public class CustomAdapter extends RecyclerView.Adapter<CustomAdapter.ViewHolder> { private String[] localDataSet; /** * Provide a reference to the type of views that you are using * (custom ViewHolder) */ public static class ViewHolder extends RecyclerView.ViewHolder { private final TextView textView; public ViewHolder(View view) { super(view); // Define click listener for the ViewHolder's View textView = (TextView) view.findViewById(R.id.textView); } public TextView getTextView() { return textView; } } /** * Initialize the dataset of the Adapter * * @param dataSet String[] containing the data to populate views to be used * by RecyclerView */ public CustomAdapter(String[] dataSet) { localDataSet = dataSet; } // Create new views (invoked by the layout manager) @Override public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) { // Create a new view, which defines the UI of the list item View view = LayoutInflater.from(viewGroup.getContext()) .inflate(R.layout.text_row_item, viewGroup, false); return new ViewHolder(view); } // Replace the contents of a view (invoked by the layout manager) @Override public void onBindViewHolder(ViewHolder viewHolder, final int position) { // Get element from your dataset at this position and replace the // contents of the view with that element viewHolder.getTextView().setText(localDataSet[position]); } // Return the size of your dataset (invoked by the layout manager) @Override public int getItemCount() { return localDataSet.length; } }
Das Layout für jedes Ansichtselement wird wie gewohnt in einer XML-Layoutdatei definiert.
In diesem Fall hat die Anwendung eine text_row_item.xml
-Datei wie diese:
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="@dimen/list_item_height"
android:layout_marginLeft="@dimen/margin_medium"
android:layout_marginRight="@dimen/margin_medium"
android:gravity="center_vertical">
<TextView
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/element_text"/>
</FrameLayout>
Nächste Schritte
Das folgende Code-Snippet zeigt, wie Sie RecyclerView
verwenden können.
Kotlin
class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) val dataset = arrayOf("January", "February", "March") val customAdapter = CustomAdapter(dataset) val recyclerView: RecyclerView = findViewById(R.id.recycler_view) recyclerView.adapter = customAdapter } }
Java
RecyclerView recyclerView = findViewById(R.id.recycler_view); recyclerView.setAdapter(customAdapter);
Die Bibliothek bietet darüber hinaus viele Möglichkeiten zur Anpassung Ihrer Implementierung. Weitere Informationen finden Sie unter Erweiterte RecyclerView-Anpassung.
Weitere Informationen
Weitere Informationen zu Tests auf Android finden Sie in den folgenden Ressourcen.