Dynamische Listen mit RecyclerView erstellen   Teil von Android Jetpack.

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

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

Wie der Name schon sagt, werden die einzelnen Elemente in RecyclerView wiederverwendet. Wenn ein Element vom Bildschirm scrollt, wird seine Ansicht von RecyclerView nicht zerstört. Stattdessen wird die Ansicht für neue Elemente wiederverwendet, die auf dem Bildschirm angezeigt werden. RecyclerView verbessert die Leistung und Reaktionsfähigkeit Ihrer App und reduziert den Stromverbrauch.

Wichtige Klassen

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

  • RecyclerView ist die ViewGroup, die die Ansichten für Ihre Daten enthält. Es handelt sich um eine Ansicht, daher fügen Sie RecyclerView Ihrem Layout auf dieselbe Weise hinzu wie jedes andere UI-Element.

  • Jedes einzelne Element in der Liste wird durch ein View-Holder-Objekt definiert. Wenn der View-Holder erstellt wird, sind ihm keine Daten zugeordnet. Nachdem der Ansichtshalter erstellt wurde, bindet RecyclerView ihn an seine Daten. Sie definieren den View-Holder, indem Sie RecyclerView.ViewHolder erweitern.

  • Die RecyclerView-Klasse fordert Ansichten an und bindet sie an ihre Daten, indem sie 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 von der RecyclerView-Bibliothek bereitgestellten Layoutmanager verwenden oder einen eigenen definieren. Alle Layoutmanager basieren auf der abstrakten Klasse LayoutManager der Bibliothek.

Wie alles zusammenpasst, sehen Sie in der RecyclerView-Beispiel-App (Kotlin) oder der RecyclerView-Beispiel-App (Java).

Schritte zum Implementieren von RecyclerView

Wenn Sie RecyclerView verwenden möchten, müssen Sie einige Dinge tun. Diese werden in den folgenden Abschnitten ausführlich erläutert.

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

  2. Legen Sie fest, wie die einzelnen Elemente in der Liste aussehen und sich verhalten sollen. Erweitern Sie die Klasse ViewHolder basierend auf diesem Design. Ihre Version von ViewHolder bietet alle Funktionen für Ihre Listenelemente. Der View-Holder ist ein Wrapper um ein View und diese Ansicht wird von RecyclerView verwaltet.

  3. Definieren Sie die Adapter, mit der Ihre Daten den ViewHolder-Ansichten zugeordnet werden.

Es gibt auch erweiterte Anpassungsoptionen, mit denen Sie Ihren RecyclerView genau an Ihre Anforderungen anpassen können.

Layout planen

Die Elemente in Ihrer RecyclerView werden von einer LayoutManager-Klasse angeordnet. Die RecyclerView-Bibliothek bietet drei Layoutmanager, die die häufigsten Layoutsituationen abdecken:

  • LinearLayoutManager ordnet die Elemente in einer eindimensionalen Liste an.
  • GridLayoutManager ordnet die Elemente in einem zweidimensionalen Raster an:
    • Wenn das Raster vertikal angeordnet ist, versucht GridLayoutManager, alle Elemente in jeder Zeile auf dieselbe Breite und Höhe einzustellen. Die Zeilen können jedoch unterschiedliche Höhen haben.
    • Wenn das Raster horizontal angeordnet ist, versucht GridLayoutManager, alle Elemente in jeder Spalte auf dieselbe Breite und Höhe einzustellen. Die Spalten können jedoch unterschiedliche Breiten haben.
  • StaggeredGridLayoutManager ist ähnlich wie GridLayoutManager, aber es ist nicht erforderlich, dass Elemente in einer Zeile dieselbe Höhe (für vertikale Raster) oder Elemente in derselben Spalte dieselbe Breite (für horizontale Raster) haben. Das Ergebnis ist, dass die Elemente in einer Zeile oder Spalte versetzt zueinander dargestellt werden können.

Sie müssen auch das Layout der einzelnen Elemente gestalten. Sie benötigen dieses Layout, wenn Sie den View-Holder entwerfen, wie im nächsten Abschnitt beschrieben.

Adapter und View-Holder implementieren

Nachdem Sie das Layout festgelegt haben, müssen Sie Adapter und ViewHolder implementieren. Diese beiden Klassen definieren gemeinsam, wie Ihre Daten dargestellt werden. ViewHolder ist ein Wrapper um ein View, das das Layout für ein einzelnes Element in der Liste enthält. Das Adapter erstellt bei Bedarf ViewHolder-Objekte und legt auch die Daten für diese Ansichten fest. Der Prozess, bei dem Ansichten ihren Daten zugeordnet werden, wird als Binden bezeichnet.

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

  • onCreateViewHolder(): RecyclerView ruft diese Methode immer dann auf, wenn ein neues ViewHolder erstellt werden muss. Mit der Methode wird die ViewHolder und die zugehörige View erstellt und initialisiert. Die Inhalte der Ansicht werden jedoch nicht ausgefüllt, da die ViewHolder noch nicht an bestimmte Daten gebunden ist.

  • 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 Viewholders auszufüllen. Wenn beispielsweise in RecyclerView eine Liste mit Namen angezeigt wird, kann die Methode den entsprechenden Namen in der Liste finden und das TextView-Widget des Viewholders ausfüllen.

  • getItemCount(): RecyclerView ruft diese Methode auf, um die Größe des Datasets abzurufen. In einer Adressbuch-App könnte das beispielsweise die Gesamtzahl der Adressen sein. RecyclerView verwendet diese Methode, um zu ermitteln, wann keine weiteren Elemente mehr angezeigt werden können.

Hier ist ein typisches Beispiel für einen einfachen Adapter mit einem verschachtelten ViewHolder, in dem eine Liste von Daten angezeigt wird. In diesem Fall wird im RecyclerView eine einfache Liste mit Textelementen angezeigt. Dem Adapter wird ein Array von Strings 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 die einzelnen Ansichtselemente wird wie gewohnt in einer XML-Layoutdatei definiert. In diesem Fall hat die App 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 Anpassung von RecyclerView.

Randlose Anzeige aktivieren

So aktivieren Sie die randlose Anzeige für ein RecyclerView:

Im folgenden Video sehen Sie ein RecyclerView mit deaktivierter (links) und aktivierter (rechts) Edge-to-Edge-Anzeige:

Beispiel für Inset-Code:

Kotlin

ViewCompat.setOnApplyWindowInsetsListener(
  findViewById(R.id.my_recycler_view)
  ) { v, insets ->
      val innerPadding = insets.getInsets(
          WindowInsetsCompat.Type.systemBars()
                  or WindowInsetsCompat.Type.displayCutout()
          // If using EditText, also add
          // "or WindowInsetsCompat.Type.ime()" to
          // maintain focus when opening the IME
      )
      v.setPadding(
          innerPadding.left,
          innerPadding.top,
          innerPadding.right,
          innerPadding.bottom)
      insets
  }
  

Java

ViewCompat.setOnApplyWindowInsetsListener(
  activity.findViewById(R.id.my_recycler_view),
  (v, insets) -> {
      Insets innerPadding = insets.getInsets(
              WindowInsetsCompat.Type.systemBars() |
                      WindowInsetsCompat.Type.displayCutout()
              // If using EditText, also add
              // "| WindowInsetsCompat.Type.ime()" to
              // maintain focus when opening the IME
      );
      v.setPadding(
              innerPadding.left,
              innerPadding.top,
              innerPadding.right,
              innerPadding.bottom
      );
      return insets;
  }
);
  

Die RecyclerView-XML-Datei:

<androidx.recyclerview.widget.RecyclerView
    android:id="@+id/my_recycler_view"
    android:clipToPadding="false"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />

Zusätzliche Ressourcen

Weitere Informationen zum Testen auf Android finden Sie in den folgenden Ressourcen.

Beispiel-Apps