Grundlagen von Android und Kotlin 07.5: Header in RecyclerView

Dieses Codelab ist Teil des Kurses „Grundlagen von Android und Kotlin“. Sie können diesen Kurs am besten nutzen, wenn Sie die Codelabs der Reihe nach durcharbeiten. Alle Codelabs des Kurses sind auf der Landingpage für Codelabs zu den Grundlagen von Android und Kotlin aufgeführt.

Einführung

In diesem Codelab erfahren Sie, wie Sie einen Header hinzufügen, der sich über die gesamte Breite der in einem RecyclerView angezeigten Liste erstreckt. Sie bauen auf der Sleep-Tracker-App aus früheren Codelabs auf.

Was Sie bereits wissen sollten

  • So erstellen Sie eine einfache Benutzeroberfläche mit einer Aktivität, Fragmenten und Ansichten.
  • Wie Sie zwischen Fragmenten wechseln und wie Sie safeArgs verwenden, um Daten zwischen Fragmenten zu übergeben.
  • Modelle, Modell-Factories, Transformationen und LiveData sowie deren Beobachter ansehen
  • So erstellen Sie eine Room-Datenbank, ein DAO und definieren Entitäten.
  • Verwendung von Coroutinen für Datenbankinteraktionen und andere zeitaufwendige Aufgaben
  • So implementieren Sie ein einfaches RecyclerView mit einem Adapter, einem ViewHolder und einem Elementlayout.
  • So implementieren Sie die Datenbindung für RecyclerView.
  • Bindungsadapter zum Transformieren von Daten erstellen und verwenden
  • So verwenden Sie GridLayoutManager.
  • Klicks auf Elemente in einem RecyclerView. erfassen und verarbeiten

Lerninhalte

  • So verwenden Sie mehr als ein ViewHolder mit einem RecyclerView, um Elemente mit einem anderen Layout hinzuzufügen. Insbesondere wird beschrieben, wie Sie mit einem zweiten ViewHolder einen Header über den in RecyclerView angezeigten Elementen hinzufügen.

Aufgaben

  • In diesem Codelab bauen Sie auf der App „TrackMySleepQuality“ aus dem vorherigen Codelab dieser Reihe auf.
  • Fügen Sie über den im RecyclerView angezeigten Schlafnächten einen Header hinzu, der die gesamte Bildschirmbreite einnimmt.

Die Sleep-Tracker-App, mit der Sie beginnen, hat drei Bildschirme, die durch Fragmente dargestellt werden, wie in der Abbildung unten zu sehen ist.

Auf dem ersten Bildschirm, der links angezeigt wird, befinden sich Schaltflächen zum Starten und Beenden des Trackings. Auf dem Display werden einige der Schlafdaten des Nutzers angezeigt. Mit der Schaltfläche Löschen werden alle Daten, die die App für den Nutzer erhoben hat, dauerhaft gelöscht. Auf dem zweiten Bildschirm in der Mitte kannst du eine Bewertung für die Schlafqualität auswählen. Der dritte Bildschirm ist eine Detailansicht, die geöffnet wird, wenn der Nutzer auf ein Element im Raster tippt.

Diese App verwendet eine vereinfachte Architektur mit einem UI-Controller, einem View-Modell und LiveData sowie einer Room-Datenbank zum Speichern von Schlafdaten.

In diesem Codelab fügen Sie dem angezeigten Raster von Elementen einen Header hinzu. Der endgültige Hauptbildschirm sieht so aus:

In diesem Codelab wird das allgemeine Prinzip zum Einbinden von Elementen mit unterschiedlichen Layouts in eine RecyclerView erläutert. Ein häufiges Beispiel sind Überschriften in Ihrer Liste oder Ihrem Raster. Eine Liste kann eine einzelne Überschrift haben, um den Inhalt des Elements zu beschreiben. Eine Liste kann auch mehrere Überschriften haben, um Elemente in einer einzelnen Liste zu gruppieren und zu trennen.

RecyclerView hat keine Informationen zu Ihren Daten oder zum Layout der einzelnen Elemente. Die LayoutManager ordnet die Elemente auf dem Bildschirm an, aber der Adapter passt die anzuzeigenden Daten an und übergibt View-Holder an die RecyclerView. Sie fügen also den Code zum Erstellen von Headern im Adapter hinzu.

Überschriften auf zwei Arten hinzufügen

In RecyclerView entspricht jedes Element in der Liste einer Indexnummer, die bei 0 beginnt. Beispiel:

[Actual Data] -> [Adapter Views]

[0: SleepNight] -> [0: SleepNight]

[1: SleepNight] -> [1: SleepNight]

[2: SleepNight] -> [2: SleepNight]

Eine Möglichkeit, einer Liste Header hinzuzufügen, besteht darin, den Adapter so zu ändern, dass ein anderes ViewHolder verwendet wird. Dazu müssen Sie die Indexe prüfen, an denen der Header angezeigt werden soll. Der Adapter ist für die Nachverfolgung des Headers verantwortlich. Wenn Sie beispielsweise oben in der Tabelle einen Header anzeigen möchten, müssen Sie beim Layout des nullbasierten Elements einen anderen ViewHolder für den Header zurückgeben. Alle anderen Elemente werden dann mit dem Header-Offset zugeordnet, wie unten dargestellt.

[Actual Data] -> [Adapter Views]

[0: Header]

[0: SleepNight] -> [1: SleepNight]

[1: SleepNight] -> [2: SleepNight]

[2: SleepNight] -> [3: SleepNight.

Eine weitere Möglichkeit, Überschriften hinzuzufügen, besteht darin, das zugrunde liegende Dataset für Ihr Datengrid zu ändern. Da alle anzuzeigenden Daten in einer Liste gespeichert sind, können Sie die Liste so ändern, dass sie Elemente enthält, die eine Überschrift darstellen. Das ist etwas einfacher zu verstehen, erfordert aber, dass Sie sich überlegen, wie Sie Ihre Objekte gestalten, damit Sie die verschiedenen Elementtypen in einer einzigen Liste kombinieren können. So implementiert, zeigt der Adapter die ihm übergebenen Elemente an. Das Element an Position 0 ist also eine Überschrift und das Element an Position 1 ist ein SleepNight, das direkt dem entspricht, was auf dem Bildschirm zu sehen ist.

[Actual Data] -> [Adapter Views]

[0: Header] -> [0: Header]

[1: SleepNight] -> [1: SleepNight]

[2: SleepNight] -> [2: SleepNight]

[3: SleepNight] -> [3: SleepNight]

Jede Methode hat Vor- und Nachteile. Durch das Ändern des Datasets ändert sich der restliche Adaptercode nicht wesentlich. Sie können Headerlogik hinzufügen, indem Sie die Liste der Daten bearbeiten. Wenn Sie hingegen einen anderen ViewHolder verwenden, indem Sie die Indexe für Überschriften prüfen, haben Sie mehr Freiheit beim Layout der Überschrift. Außerdem kann der Adapter so die Anpassung der Daten an die Ansicht übernehmen, ohne die zugrunde liegenden Daten zu ändern.

In diesem Codelab aktualisieren Sie RecyclerView, um am Anfang der Liste eine Kopfzeile anzuzeigen. In diesem Fall verwendet Ihre App ein anderes ViewHolder für den Header als für die Datenelemente. Die App prüft den Index der Liste, um zu ermitteln, welche ViewHolder verwendet werden soll.

Schritt 1: DataItem-Klasse erstellen

Um den Typ des Elements zu abstrahieren und den Adapter nur mit „Elementen“ arbeiten zu lassen, können Sie eine Datenhalterklasse erstellen, die entweder ein SleepNight oder ein Header darstellt. Ihr Dataset ist dann eine Liste von Dateninhaberelementen.

Sie können die Starter-App entweder von GitHub herunterladen oder die SleepTracker-App weiter verwenden, die Sie im vorherigen Codelab erstellt haben.

  1. Laden Sie den Code RecyclerViewHeaders-Starter von GitHub herunter. Das Verzeichnis RecyclerViewHeaders-Starter enthält die Starter-Version der SleepTracker-App, die für dieses Codelab benötigt wird. Sie können auch mit Ihrer fertigen App aus dem vorherigen Codelab fortfahren.
  2. Öffne SleepNightAdapter.kt.
  3. Definieren Sie unter der Klasse SleepNightListener auf oberster Ebene eine Klasse sealed mit dem Namen DataItem, die ein Datenelement darstellt.

    Eine sealed-Klasse definiert einen geschlossenen Typ. Das bedeutet, dass alle Unterklassen von DataItem in dieser Datei definiert werden müssen. Daher ist die Anzahl der Unterklassen dem Compiler bekannt. Es ist nicht möglich, dass in einem anderen Teil Ihres Codes ein neuer Typ von DataItem definiert wird, der Ihren Adapter beschädigen könnte.
sealed class DataItem {

 }
  1. Definieren Sie im Hauptteil der DataItem-Klasse zwei Klassen, die die verschiedenen Arten von Datenelementen darstellen. Die erste ist eine SleepNightItem, die ein Wrapper um eine SleepNight ist. Sie akzeptiert also einen einzelnen Wert namens sleepNight. Damit sie Teil der versiegelten Klasse ist, muss sie DataItem erweitern.
data class SleepNightItem(val sleepNight: SleepNight): DataItem()
  1. Die zweite Klasse ist Header, die einen Header darstellt. Da ein Header keine tatsächlichen Daten enthält, können Sie ihn als object deklarieren. Das bedeutet, dass es immer nur eine Instanz von Header geben wird. Lassen Sie es noch einmal um DataItem verlängern.
object Header: DataItem()
  1. Definieren Sie in DataItem auf Klassenebene eine abstract-Long-Property mit dem Namen id. Wenn der Adapter DiffUtil verwendet, um zu ermitteln, ob und wie sich ein Element geändert hat, muss die DiffItemCallback die ID jedes Elements kennen. Es wird ein Fehler angezeigt, da SleepNightItem und Header die abstrakte Eigenschaft id überschreiben müssen.
abstract val id: Long
  1. Überschreiben Sie in SleepNightItem id, um nightId zurückzugeben.
override val id = sleepNight.nightId
  1. Überschreiben Sie in Header id, um Long.MIN_VALUE zurückzugeben. Das ist eine sehr, sehr kleine Zahl (buchstäblich -2 hoch 63). Daher kommt es nie zu Konflikten mit vorhandenen nightId.
override val id = Long.MIN_VALUE
  1. Der fertige Code sollte so aussehen und die App sollte ohne Fehler erstellt werden.
sealed class DataItem {
    abstract val id: Long
    data class SleepNightItem(val sleepNight: SleepNight): DataItem()      {
        override val id = sleepNight.nightId
    }

    object Header: DataItem() {
        override val id = Long.MIN_VALUE
    }
}

Schritt 2: ViewHolder für den Header erstellen

  1. Erstellen Sie das Layout für den Header in einer neuen Layoutressourcendatei mit dem Namen header.xml , in der ein TextView angezeigt wird. Das ist nicht besonders spannend, daher hier der Code.
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/text"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:textAppearance="?android:attr/textAppearanceLarge"
    android:text="Sleep Results"
    android:padding="8dp" />
  1. Extrahieren Sie "Sleep Results" in eine String-Ressource und nennen Sie sie header_text.
<string name="header_text">Sleep Results</string>
  1. Erstelle in SleepNightAdapter.kt innerhalb von SleepNightAdapter und über der Klasse ViewHolder eine neue Klasse TextViewHolder. Diese Klasse instanziiert das Layout textview.xml und gibt eine TextViewHolder-Instanz zurück. Da Sie das schon einmal gemacht haben, finden Sie hier den Code. Sie müssen View und R importieren:
    class TextViewHolder(view: View): RecyclerView.ViewHolder(view) {
        companion object {
            fun from(parent: ViewGroup): TextViewHolder {
                val layoutInflater = LayoutInflater.from(parent.context)
                val view = layoutInflater.inflate(R.layout.header, parent, false)
                return TextViewHolder(view)
            }
        }
    }

Schritt 3: SleepNightAdapter aktualisieren

Als Nächstes müssen Sie die Erklärung von SleepNightAdapter aktualisieren. Anstatt nur einen Typ von ViewHolder zu unterstützen, muss er jeden Typ von View-Holder verwenden können.

Artikeltypen definieren

  1. Definieren Sie in SleepNightAdapter.kt auf der obersten Ebene unter den import-Anweisungen und über SleepNightAdapter zwei Konstanten für die Ansichtstypen.

    Im RecyclerView muss der Ansichtstyp jedes Elements angegeben werden, damit ihm der richtige View-Holder zugewiesen werden kann.
    private val ITEM_VIEW_TYPE_HEADER = 0
    private val ITEM_VIEW_TYPE_ITEM = 1
  1. Erstellen Sie in SleepNightAdapter eine Funktion, um getItemViewType() zu überschreiben und je nach Typ des aktuellen Elements den richtigen Header oder die richtige Elementkonstante zurückzugeben.
override fun getItemViewType(position: Int): Int {
        return when (getItem(position)) {
            is DataItem.Header -> ITEM_VIEW_TYPE_HEADER
            is DataItem.SleepNightItem -> ITEM_VIEW_TYPE_ITEM
        }
    }

SleepNightAdapter-Definition aktualisieren

  1. Aktualisieren Sie in der Definition von SleepNightAdapter das erste Argument für ListAdapter von SleepNight auf DataItem.
  2. Ändern Sie in der Definition von SleepNightAdapter das zweite generische Argument für ListAdapter von SleepNightAdapter.ViewHolder in RecyclerView.ViewHolder. Es werden einige Fehler für erforderliche Aktualisierungen angezeigt und die Kopfzeile der Klasse sollte wie unten aussehen.
class SleepNightAdapter(val clickListener: SleepNightListener):
       ListAdapter<DataItem, RecyclerView.ViewHolder>(SleepNightDiffCallback()) {

onCreateViewHolder() aktualisieren

  1. Ändern Sie die Signatur von onCreateViewHolder(), sodass ein RecyclerView.ViewHolder zurückgegeben wird.
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder
  1. Erweitern Sie die Implementierung der onCreateViewHolder()-Methode, um den entsprechenden View-Holder für jeden Elementtyp zu testen und zurückzugeben. Ihre aktualisierte Methode sollte wie im Code unten aussehen.
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
        return when (viewType) {
            ITEM_VIEW_TYPE_HEADER -> TextViewHolder.from(parent)
            ITEM_VIEW_TYPE_ITEM -> ViewHolder.from(parent)
            else -> throw ClassCastException("Unknown viewType ${viewType}")
        }
    }

onBindViewHolder() aktualisieren

  1. Ändern Sie den Parametertyp von onBindViewHolder() von ViewHolder in RecyclerView.ViewHolder.
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int)
  1. Fügen Sie eine Bedingung hinzu, damit Daten nur dann dem View-Holder zugewiesen werden, wenn er ein ViewHolder ist.
        when (holder) {
            is ViewHolder -> {...}
  1. Wandeln Sie den von getItem() zurückgegebenen Objekttyp in DataItem.SleepNightItem um. Die fertige onBindViewHolder()-Funktion sollte so aussehen.
  override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
        when (holder) {
            is ViewHolder -> {
                val nightItem = getItem(position) as DataItem.SleepNightItem
                holder.bind(nightItem.sleepNight, clickListener)
            }
        }
    }

DiffUtil-Callbacks aktualisieren

  1. Ändern Sie die Methoden in SleepNightDiffCallback so, dass Ihre neue Klasse DataItem anstelle von SleepNight verwendet wird. Unterdrücken Sie die Lint-Warnung wie im folgenden Code gezeigt.
class SleepNightDiffCallback : DiffUtil.ItemCallback<DataItem>() {
    override fun areItemsTheSame(oldItem: DataItem, newItem: DataItem): Boolean {
        return oldItem.id == newItem.id
    }
    @SuppressLint("DiffUtilEquals")
    override fun areContentsTheSame(oldItem: DataItem, newItem: DataItem): Boolean {
        return oldItem == newItem
    }
}

Header hinzufügen und senden

  1. Definieren Sie in SleepNightAdapter unter onCreateViewHolder() eine Funktion addHeaderAndSubmitList(), wie unten gezeigt. Diese Funktion akzeptiert eine Liste von SleepNight. Anstatt submitList() zu verwenden, das von ListAdapter bereitgestellt wird, um Ihre Liste einzureichen, verwenden Sie diese Funktion, um einen Header hinzuzufügen und die Liste dann einzureichen.
fun addHeaderAndSubmitList(list: List<SleepNight>?) {}
  1. Wenn die übergebene Liste in addHeaderAndSubmitList() null ist, gib nur einen Header zurück. Andernfalls hänge den Header an den Anfang der Liste an und sende die Liste.
val items = when (list) {
                null -> listOf(DataItem.Header)
                else -> listOf(DataItem.Header) + list.map { DataItem.SleepNightItem(it) }
            }
submitList(items)
  1. Öffnen Sie SleepTrackerFragment.kt und ändern Sie den Aufruf von submitList() in addHeaderAndSubmitList().
  1. Führen Sie Ihre App aus und beobachten Sie, wie der Header als erstes Element in der Liste der Schlafdaten angezeigt wird.

Für diese App müssen zwei Dinge behoben werden. Eines ist sichtbar, das andere nicht.

  • Der Header wird oben links angezeigt und ist nicht leicht zu erkennen.
  • Bei einer kurzen Liste mit einem Header spielt das keine große Rolle, aber Sie sollten die Listenbearbeitung in addHeaderAndSubmitList() nicht im UI-Thread durchführen. Stellen Sie sich eine Liste mit Hunderten von Elementen, mehreren Überschriften und Logik vor, um zu entscheiden, wo Elemente eingefügt werden müssen. Diese Arbeit gehört in eine Coroutine.

addHeaderAndSubmitList() für die Verwendung von Coroutinen ändern:

  1. Definieren Sie auf der obersten Ebene in der SleepNightAdapter-Klasse eine CoroutineScope mit Dispatchers.Default.
private val adapterScope = CoroutineScope(Dispatchers.Default)
  1. Starte in addHeaderAndSubmitList() eine Coroutine im adapterScope, um die Liste zu bearbeiten. Wechseln Sie dann zum Kontext Dispatchers.Main, um die Liste zu senden, wie im folgenden Code gezeigt.
 fun addHeaderAndSubmitList(list: List<SleepNight>?) {
        adapterScope.launch {
            val items = when (list) {
                null -> listOf(DataItem.Header)
                else -> listOf(DataItem.Header) + list.map { DataItem.SleepNightItem(it) }
            }
            withContext(Dispatchers.Main) {
                submitList(items)
            }
        }
    }
  1. Ihr Code sollte kompiliert und ausgeführt werden und Sie werden keinen Unterschied feststellen.

Derzeit hat der Header dieselbe Breite wie die anderen Elemente im Raster und nimmt horizontal und vertikal jeweils eine Spalte ein. In das gesamte Raster passen horizontal drei Elemente mit einer Spaltenbreite. Der Header sollte also horizontal drei Spalten umfassen.

Um die Headerbreite zu korrigieren, müssen Sie GridLayoutManager mitteilen, wann die Daten über alle Spalten verteilt werden sollen. Dazu konfigurieren Sie SpanSizeLookup für ein GridLayoutManager. Dies ist ein Konfigurationsobjekt, das von GridLayoutManager verwendet wird, um zu bestimmen, wie viele Spannen für jedes Element in der Liste verwendet werden sollen.

  1. Öffnen Sie SleepTrackerFragment.kt.
  2. Suchen Sie den Code, in dem Sie manager definieren, gegen Ende von onCreateView().
val manager = GridLayoutManager(activity, 3)
  1. Definieren Sie manager.spanSizeLookup unter manager wie gezeigt. Sie müssen ein object erstellen, da setSpanSizeLookup kein Lambda akzeptiert. Um eine object in Kotlin zu erstellen, geben Sie object : classname ein, in diesem Fall GridLayoutManager.SpanSizeLookup.
manager.spanSizeLookup = object : GridLayoutManager.SpanSizeLookup() {
}
  1. Möglicherweise erhalten Sie einen Compilerfehler, wenn Sie den Konstruktor aufrufen. Wenn Sie das tun, öffnen Sie das Intention-Menü mit Option+Enter (Mac) oder Alt+Enter (Windows), um den Konstruktoraufruf anzuwenden.
  1. Dann erhalten Sie einen Fehler für object, dass Sie Methoden überschreiben müssen. Setzen Sie den Cursor auf object, drücken Sie Option+Enter (Mac) oder Alt+Enter (Windows), um das Intentionen-Menü zu öffnen, und überschreiben Sie dann die Methode getSpanSize().
  1. Geben Sie im Textkörper von getSpanSize() die richtige Spannenlänge für jede Position zurück. Position 0 hat eine Spannenbreite von 3, die anderen Positionen haben eine Spannenbreite von 1. Ihr fertiger Code sollte so aussehen:
    manager.spanSizeLookup = object : GridLayoutManager.SpanSizeLookup() {
            override fun getSpanSize(position: Int) =  when (position) {
                0 -> 3
                else -> 1
            }
        }
  1. Um das Aussehen des Headers zu verbessern, öffnen Sie header.xml und fügen Sie diesen Code in die Layoutdatei header.xml ein.
android:textColor="@color/white_text_color"
android:layout_marginStart="16dp"
android:layout_marginTop="16dp"
android:layout_marginEnd="16dp"
android:background="@color/colorAccent"
  1. Führen Sie die App aus. Sie sollte wie im Screenshot unten aussehen.

Glückwunsch! Fertig!

Android Studio-Projekt: RecyclerViewHeaders

  • Ein Header ist in der Regel ein Element, das sich über die gesamte Breite einer Liste erstreckt und als Titel oder Trennzeichen dient. Eine Liste kann eine einzelne Überschrift zur Beschreibung des Inhalts der Elemente oder mehrere Überschriften zum Gruppieren und Trennen von Elementen enthalten.
  • Ein RecyclerView kann mehrere View-Holder verwenden, um eine heterogene Gruppe von Elementen wie Überschriften und Listenelemente aufzunehmen.
  • Eine Möglichkeit, Header hinzuzufügen, besteht darin, den Adapter so zu ändern, dass ein anderes ViewHolder verwendet wird. Dazu müssen Sie die Indexe prüfen, an denen der Header angezeigt werden soll. Der Adapter ist für die Nachverfolgung des Headers verantwortlich.
  • Eine weitere Möglichkeit, Überschriften hinzuzufügen, besteht darin, das zugrunde liegende Dataset (die Liste) für Ihr Datengrid zu ändern. Das haben Sie in diesem Codelab getan.

Dies sind die wichtigsten Schritte zum Hinzufügen einer Kopfzeile:

  • Abstrahieren Sie die Daten in Ihrer Liste, indem Sie ein DataItem erstellen, das eine Überschrift oder Daten enthalten kann.
  • Erstellen Sie im Adapter einen View-Holder mit einem Layout für den Header.
  • Aktualisieren Sie den Adapter und seine Methoden, damit jede Art von RecyclerView.ViewHolder verwendet werden kann.
  • Geben Sie in onCreateViewHolder() den richtigen Typ des View-Holders für das Datenelement zurück.
  • Aktualisieren Sie SleepNightDiffCallback, damit es mit der Klasse DataItem funktioniert.
  • Erstellen Sie eine addHeaderAndSubmitList()-Funktion, die Coroutinen verwendet, um dem Dataset den Header hinzuzufügen, und dann submitList() aufruft.
  • Implementieren Sie GridLayoutManager.SpanSizeLookup(), damit der Header nur drei Spalten breit ist.

Udacity-Kurs:

Android-Entwicklerdokumentation:

In diesem Abschnitt werden mögliche Hausaufgaben für Schüler und Studenten aufgeführt, die dieses Codelab im Rahmen eines von einem Kursleiter geleiteten Kurses durcharbeiten. Es liegt in der Verantwortung des Kursleiters, Folgendes zu tun:

  • Weisen Sie bei Bedarf Aufgaben zu.
  • Teilen Sie den Schülern/Studenten mit, wie sie Hausaufgaben abgeben können.
  • Benoten Sie die Hausaufgaben.

Lehrkräfte können diese Vorschläge nach Belieben nutzen und auch andere Hausaufgaben zuweisen, die sie für angemessen halten.

Wenn Sie dieses Codelab selbst durcharbeiten, können Sie mit diesen Hausaufgaben Ihr Wissen testen.

Beantworten Sie diese Fragen

Frage 1

Welche der folgenden Aussagen zu ViewHolder ist richtig?

▢ Ein Adapter kann mehrere ViewHolder-Klassen verwenden, um Header und verschiedene Datentypen zu speichern.

▢ Sie können genau einen View-Holder für Daten und einen View-Holder für einen Header haben.

▢ Ein RecyclerView unterstützt mehrere Arten von Headern, die Daten müssen jedoch einheitlich sein.

▢ Wenn Sie eine Kopfzeile hinzufügen, erstellen Sie eine Unterklasse von RecyclerView, um die Kopfzeile an der richtigen Position einzufügen.

Frage 2

Wann sollten Sie Coroutinen mit einem RecyclerView verwenden? Wählen Sie alle zutreffenden Aussagen aus.

▢ Nie. Ein RecyclerView ist ein UI-Element und sollte keine Coroutinen verwenden.

▢ Verwenden Sie Coroutinen für lang andauernde Aufgaben, die die Benutzeroberfläche verlangsamen könnten.

▢ Listenbearbeitungen können lange dauern und sollten immer mit Coroutinen erfolgen.

▢ Verwenden Sie Coroutinen mit Suspend-Funktionen, um zu vermeiden, dass der Hauptthread blockiert wird.

Frage 3

Was müssen Sie NICHT tun, wenn Sie mehrere ViewHolder verwenden?

▢ Geben Sie im ViewHolder mehrere Layoutdateien an, die nach Bedarf eingefügt werden sollen.

▢ Geben Sie in onCreateViewHolder() den richtigen Typ des View-Holders für das Datenelement zurück.

▢ Binden Sie Daten in onBindViewHolder() nur, wenn der View-Holder der richtige View-Holder-Typ für das Datenelement ist.

▢ Generalisieren Sie die Signatur der Adapterklasse, damit sie beliebige RecyclerView.ViewHolder akzeptiert.

Nächste Lektion starten: 8.1 Daten aus dem Internet abrufen

Links zu anderen Codelabs in diesem Kurs finden Sie auf der Landingpage für Android Kotlin Fundamentals-Codelabs.