Dynamische Listen mit RecyclerView erstellen Teil von Android Jetpack

Schreiben Sie jetzt
Jetpack Compose ist das empfohlene UI-Toolkit für Android. Hier erfahren Sie, wie Sie in „Compose“ mit Layouts arbeiten.

RecyclerView vereinfacht die effiziente Darstellung großer Datenmengen. Sie stellen die Daten bereit und legen fest, wie die einzelnen Elemente aussehen sollen. Die RecyclerView-Bibliothek erstellt dann die Elemente 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, zerstört RecyclerView seine Ansicht nicht. Stattdessen verwendet RecyclerView die Ansicht für neue Elemente, die auf dem Bildschirm gescrollt wurden. RecyclerView verbessert die Leistung und Reaktionsfähigkeit Ihrer App und senkt den Stromverbrauch.

Schlüsselklassen

Mehrere Klassen arbeiten zusammen, um Ihre dynamische Liste zu erstellen.

  • RecyclerView ist die ViewGroup, die die Ansichten enthält, die Ihren Daten entsprechen. Es ist selbst eine Ansicht, also fügen Sie RecyclerView Ihrem Layout genauso hinzu wie jedes andere UI-Element.

  • Jedes einzelne Element in der Liste wird durch ein Inhaberobjekt definiert. Wenn der Ansichtsinhaber erstellt wird, sind ihm keine Daten zugeordnet. Nachdem der Ansichtsinhaber erstellt wurde, wird er von RecyclerView an seine Daten gebunden. Sie definieren den Ansichtsinhaber, indem Sie RecyclerView.ViewHolder erweitern.

  • RecyclerView fordert Ansichten an und bindet die Ansichten an ihre Daten. Dazu werden Methoden im adapter. Sie definieren den Adapter, indem Sie RecyclerView.Adapter erweitern.

  • Im Layout-Manager werden die einzelnen Elemente in der Liste angeordnet. Sie können einen der in der RecyclerView-Bibliothek bereitgestellten Layout-Manager verwenden oder einen eigenen Layoutmanager definieren. Layoutmanager basieren alle auf der abstrakten LayoutManager-Klasse der Bibliothek.

In der Beispiel-App „RecyclerView“ (Kotlin) oder der Beispiel-App „RecyclerView“ (Java) sehen Sie, wie alle Teile zusammenpassen.

Schritte zur Implementierung von RecyclerView

Wenn Sie RecyclerView verwenden möchten, müssen Sie einige Schritte ausführen, die in den folgenden Abschnitten ausführlich erläutert werden.

  1. Legen Sie fest, wie die Liste oder das Raster aussehen soll. Normalerweise können Sie einen der Standard-Layoutmanager der RecyclerView-Bibliothek verwenden.

  2. Gestalten Sie das Aussehen und die Funktionsweise der einzelnen Elemente in der Liste. Erweitern Sie basierend auf diesem Design die ViewHolder-Klasse. Ihre Version von ViewHolder bietet alle Funktionen für Listenelemente. Der Datenansichtshalter ist ein Wrapper um einen View, der von RecyclerView verwaltet wird.

  3. Definieren Sie die Adapter, die Ihre Daten mit den ViewHolder-Datenansichten verknüpft.

Mithilfe der erweiterten Anpassungsoptionen können Sie RecyclerView genau an Ihre Anforderungen anpassen.

Layout planen

Die Elemente in RecyclerView sind nach einer LayoutManager-Klasse geordnet. Die RecyclerView-Bibliothek bietet drei Layout-Manager, die die häufigsten Layoutsituationen bewältigen:

  • 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 dieselbe Breite und Höhe zu haben. Unterschiedliche Spalten können jedoch unterschiedliche Breiten haben.
  • StaggeredGridLayoutManager ähnelt GridLayoutManager, allerdings müssen die Elemente in einer Zeile bei vertikalen Rastern nicht dieselbe Höhe oder bei horizontalen Rastern Elemente in derselben Spalte dieselbe Breite haben. Das hat zur Folge, dass die Elemente in einer Zeile oder Spalte am Ende voneinander abweichen können.

Außerdem müssen Sie 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 Datenansichten implementieren

Nachdem du das Layout festgelegt hast, musst du Adapter und ViewHolder implementieren. Diese beiden Klassen bestimmen zusammen, wie Ihre Daten dargestellt werden. ViewHolder ist ein Wrapper um ein View-Element, das das Layout für ein einzelnes Element in der Liste enthält. Adapter erstellt nach Bedarf ViewHolder-Objekte und legt außerdem die Daten für diese Ansichten fest. Das Verknüpfen von Ansichten mit ihren Daten wird als Bindung bezeichnet.

Wenn Sie Ihren Adapter definieren, werden drei Schlüsselmethoden überschrieben:

  • onCreateViewHolder(): RecyclerView ruft diese Methode immer dann auf, wenn eine neue ViewHolder erstellt werden muss. Die Methode erstellt und initialisiert die ViewHolder und die zugehörigen View, füllt aber nicht den Inhalt der Ansicht – die ViewHolder wurde noch nicht an bestimmte Daten gebunden.

  • onBindViewHolder(): RecyclerView ruft diese Methode auf, um eine ViewHolder mit Daten zu verknüpfen. Die Methode ruft die entsprechenden Daten ab und füllt das Layout des Ansichtsinhabers mit diesen Daten. Wenn mit RecyclerView beispielsweise eine Liste von Namen angezeigt wird, kann die Methode den entsprechenden Namen in der Liste finden und das Widget TextView des Ansichtsinhabers ausfüllen.

  • 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 ermittelt damit, wann keine Elemente mehr angezeigt werden können.

Hier ein typisches Beispiel für einen einfachen Adapter mit einem verschachtelten ViewHolder, der eine Liste von Daten anzeigt. In diesem Fall zeigt RecyclerView eine einfache Liste von Textelementen an. Dem Adapter wird ein Array von Strings übergeben, die den Text für die ViewHolder-Elemente enthalten.

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.layoutManager = LinearLayoutManager(this)
        recyclerView.adapter = customAdapter

    }

}

Java


RecyclerView recyclerView = findViewById(R.id.recycler_view);
recyclerView.layoutManager = new LinearLayoutManager(this)
recyclerView.setAdapter(customAdapter);

Die Bibliothek bietet auch viele Möglichkeiten, Ihre Implementierung anzupassen. Weitere Informationen finden Sie unter Erweiterte RecyclerView-Anpassung.

Zusätzliche Ressourcen

Weitere Informationen zu Tests unter Android finden Sie in den folgenden Ressourcen.

Beispiel-Apps