Dynamische Listen mit RecyclerView erstellen   Teil von Android Jetpack.

Compose ausprobieren
Jetpack Compose ist das empfohlene UI-Toolkit für Android. Informationen zum Arbeiten mit Layouts in Compose

Mit RecyclerView lassen sich große Datenmengen einfach effizient darstellen. Sie stellen die Daten bereit und definieren, wie die einzelnen Elemente aussehen. Die RecyclerView-Bibliothek erstellt die Elemente dann dynamisch, wenn sie benötigt werden.

Wie der Name schon sagt, recycelt RecyclerView diese einzelnen Elemente. Wenn ein Element vom Bildschirm herausgescrollt wird, wird die Ansicht von RecyclerView nicht zerstört. 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 reduziert den Energieverbrauch.

Wichtige Klassen

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

  • RecyclerView ist die ViewGroup, die die Ansichten enthält, die Ihren Daten entsprechen. Da es sich um eine Ansicht handelt, fügen Sie RecyclerView Ihrem Layout auf die gleiche Weise hinzu wie jedes andere UI-Element.

  • Jedes einzelne Element in der Liste wird durch ein Viewholder-Objekt definiert. Beim Erstellen des Ansichtsholders sind keine Daten damit verknüpft. Nachdem der Viewholder erstellt wurde, bindet RecyclerView ihn an seine Daten. Sie definieren den Viewholder, indem Sie RecyclerView.ViewHolder erweitern.

  • Der RecyclerView fordert Ansichten an und bindet sie an ihre Daten, indem er Methoden im Adapter aufruft. Sie definieren den Adapter, indem Sie RecyclerView.Adapter erweitern.

  • Der Layout-Manager ordnet die einzelnen Elemente in Ihrer Liste an. Sie können einen der Layoutmanager verwenden, die von der RecyclerView-Bibliothek bereitgestellt werden, oder einen eigenen definieren. Layout-Manager basieren alle auf der abstrakten Klasse LayoutManager der Bibliothek.

In der RecyclerView-Beispielanwendung (Kotlin) oder der RecyclerView-Beispielanwendung (Java) sehen Sie, wie alle Teile zusammenpassen.

Schritte zur Implementierung des 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. Legen Sie fest, wie jedes Element in der Liste aussieht und sich verhält. Erweitern Sie anhand dieses Designs die Klasse ViewHolder. Ihre Version von ViewHolder bietet alle Funktionen für Ihre Listenelemente. Der View-Holder ist ein View-Wrapper und diese Ansicht wird von RecyclerView verwaltet.

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

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

Layout planen

Die Elemente in Ihrem RecyclerView werden nach einer LayoutManager-Klasse angeordnet. Die RecyclerView-Bibliothek bietet drei Layoutmanager, 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 geben. Die 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 geben. Die Spalten können jedoch unterschiedliche Breiten haben.
  • StaggeredGridLayoutManagerähnelt GridLayoutManager, aber die Elemente in einer Zeile müssen nicht dieselbe Höhe (bei vertikalen Rastern) oder die Elemente in derselben Spalte nicht dieselbe Breite (bei horizontalen Rastern) haben. Das Ergebnis ist, dass die Elemente in einer Zeile oder Spalte versetzt zueinander sein 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 Ansichtshalter implementieren

Nachdem Sie das Layout festgelegt haben, müssen Sie Adapter und ViewHolder implementieren. Diese beiden Klassen legen gemeinsam fest, wie Ihre Daten angezeigt werden. ViewHolder ist ein Wrapper um ein View-Element, das das Layout für ein einzelnes Element in der Liste enthält. Der 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.

Wenn Sie Ihren Adapter definieren, überschreiben Sie drei wichtige Methoden:

  • 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örige View, füllt aber nicht den Inhalt der Ansicht aus. 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 verwendet sie, um das Layout des Ansichtsholders auszufüllen. Wenn in RecyclerView beispielsweise eine Liste mit Namen angezeigt wird, kann die Methode den entsprechenden Namen in der Liste finden und das TextView-Widget des Ansichtsholders ausfüllen.

  • getItemCount(): RecyclerView ruft diese Methode auf, um die Größe des Datensatzes zu ermitteln. In einer Adressbuchanwendung kann dies beispielsweise die Gesamtzahl der Adressen sein. Anhand dieser Informationen ermittelt RecyclerView, wann keine Elemente mehr angezeigt werden können.

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

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 enthält die App eine text_row_item.xml-Datei mit folgendem Inhalt:

<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 außerdem viele Möglichkeiten, Ihre Implementierung anzupassen. Weitere Informationen finden Sie unter Erweiterte RecyclerView-Anpassung.

Weitere Informationen

Weitere Informationen zu Tests auf Android-Geräten finden Sie in den folgenden Ressourcen.

Beispiel-Apps