Dieses Codelab ist Teil des Android Kotlin Fundamentals-Kurss. Sie profitieren von diesem Kurs, wenn Sie nacheinander die Codelabs durcharbeiten. Alle Kurs-Codelabs finden Sie auf der Landingpage für Kotlin-Grundlagen für Android-Entwickler.
Einführung
Im vorherigen Codelab hast du die TrackMySleepquality-App aktualisiert, sodass Daten zur Schlafqualität in einem RecyclerView
angezeigt werden. Die Techniken, die Sie bei der Erstellung Ihrer ersten RecyclerView
gelernt haben, reichen für die meisten RecyclerViews
aus, die einfache Listen zeigen, die nicht zu groß sind. Allerdings gibt es eine Reihe von Techniken, die RecyclerView
für große Listen effizienter machen und Ihren Code einfacher für die Pflege und Erweiterung komplexer Listen und Raster erleichtern.
In diesem Codelab baust du auf der Schlaf-Tracker-App aus dem vorherigen Codelab auf. Sie lernen, die Liste der Schlafdaten effektiver zu aktualisieren und lernen, wie man die Datenbindung mit RecyclerView
nutzt. Wenn Sie die App aus dem vorherigen Codelab nicht haben, können Sie den Startcode für dieses Codelab herunterladen.
Was Sie bereits wissen sollten
- Erstellen einer einfachen Benutzeroberfläche mit einer Aktivität, Fragmenten und Ansichten.
- Die Navigation zwischen den Fragmenten und die Verwendung von
safeArgs
zum Übergeben von Daten zwischen Fragmenten. - Modelle ansehen, Modellfabriken, Transformationen und
LiveData
und ihre Betrachter ansehen. - Erstellen einer
Room
-Datenbank, eines DAO und Definieren von Entitäten. - Koroutinen für Datenbanken und andere langlebige Aufgaben verwenden
- Einfache
RecyclerView
mit einemAdapter
-,ViewHolder
- und Elementlayout implementieren
Lerninhalte
- Mit
DiffUtil
kannst du eine vonRecyclerView
angezeigte Liste effizient aktualisieren. - So verwenden Sie die Datenbindung mit
RecyclerView
. - Bindungsadapter für die Transformation von Daten verwenden
Aufgaben
- baue auf die TrackMySleepquality-App des vorherigen Codelabs in dieser Serie auf.
- Aktualisiere die
SleepNightAdapter
, um die Liste mitDiffUtil
effizient zu aktualisieren. - Implementiere die Datenbindung für die
RecyclerView
mithilfe von Bindungsadaptern, um die Daten zu transformieren.
Die Schlaf-Tracker-App hat zwei Bildschirme, die als Fragmente dargestellt sind (siehe Abbildung unten).
Auf dem ersten Bildschirm auf der linken Seite finden Sie Schaltflächen zum Starten und Beenden der Aufzeichnung. Auf dem Bildschirm werden einige Schlafdaten des Nutzers angezeigt. Mit der Schaltfläche Löschen werden alle Daten gelöscht, die die App für den Nutzer erfasst hat. Auf dem zweiten Bildschirm rechts wird die Qualität des Schlafs angezeigt.
Diese App ist so konzipiert, dass sie einen UI-Controller, ViewModel
und LiveData
sowie eine Room
-Datenbank verwendet, um Schlafdaten zu speichern.
Die Schlafdaten werden in RecyclerView
angezeigt. In diesem Codelab erstellen Sie DiffUtil
und die Datenbindung für RecyclerView
. Nach diesem Codelab wird Ihre App genau gleich aussehen, aber sie ist effizienter und einfacher zu verwalten und zu verwalten.
Sie können die SleepTracker-App aus dem vorherigen Codelab weiterhin verwenden oder die RecyclerViewDiffUtilDataData-Starter App von GitHub herunterladen.
- Laden Sie bei Bedarf die RecyclerViewDiffUtilDataBindung-Starter-App von GitHub herunter und öffnen Sie das Projekt in Android Studio.
- Führen Sie die App aus.
- Öffnen Sie die Datei
SleepNightAdapter.kt
. - Prüfen Sie den Code, um sich mit der Struktur der App vertraut zu machen. Unten sehen Sie eine Zusammenfassung der Verwendung von
RecyclerView
mit dem Adaptermuster zur Darstellung von Schlafdaten für den Nutzer.
- Anhand der Nutzereingabe erstellt die App eine Liste von
SleepNight
-Objekten. JedesSleepNight
-Objekt repräsentiert eine einzelne Nacht, die Dauer und die Qualität des Schlafs. - Mit dem
SleepNightAdapter
wird die Liste derSleepNight
-Objekte in etwas angepasst, dasRecyclerView
verwenden und anzeigen kann. - Mit dem Adapter
SleepNightAdapter
werdenViewHolders
generiert. Diese enthalten die Ansichten, Daten und Metainformationen für die Recycler-Ansicht, die die Daten darstellen. RecyclerView
verwendetSleepNightAdapter
, um zu bestimmen, wie viele Elemente angezeigt werden können (getItemCount()
).RecyclerView
verwendetonCreateViewHolder()
undonBindViewHolder()
, um Aufrufhalter an Daten zur Anzeige zu binden.
Die Parameter „unDataDataSetChanged()“ ist ineffizient
Damit RecyclerView
informiert wird, dass sich ein Element in der Liste geändert hat und aktualisiert werden muss, wird mit dem aktuellen Code notifyDataSetChanged()
in SleepNightAdapter
aufgerufen (siehe unten).
var data = listOf<SleepNight>()
set(value) {
field = value
notifyDataSetChanged()
}
notifyDataSetChanged()
teilt RecyclerView
jedoch mit, dass die gesamte Liste möglicherweise ungültig ist. Deshalb wird RecyclerView
jedes Element in der Liste noch einmal neu verknüpfen, auch nicht auf dem Bildschirm sichtbar. Das ist sehr viel Arbeit. Bei umfangreichen oder komplexen Listen kann es einige Zeit dauern, bis das Display flackert oder ruckelt, wenn der Nutzer durch die Liste scrollt.
Um das Problem zu beheben, kannst du RecyclerView
genau mitteilen, was sich geändert hat. RecyclerView
kann dann nur die Ansichten aktualisieren, die sich auf dem Bildschirm geändert haben.
RecyclerView
hat eine umfangreiche API zum Aktualisieren eines einzelnen Elements. Mit notifyItemChanged()
kannst du RecyclerView
mitteilen, dass sich ein Element geändert hat, und ähnliche Funktionen für Elemente verwenden, die hinzugefügt, entfernt oder verschoben wurden. Sie können das alles manuell erledigen, aber die Aufgabe ist nicht schwierig und kann ziemlich viel Code beinhalten.
Zum Glück gibt es die bessere Möglichkeit.
DiffUtil ist effizient und übernimmt die Arbeit für Sie
RecyclerView
hat eine Klasse namens DiffUtil
, mit der die Unterschiede zwischen zwei Listen berechnet werden. DiffUtil
verwendet eine alte Liste und eine neue Liste und ermittelt die Unterschiede. Elemente, die hinzugefügt, entfernt oder geändert wurden, werden gefunden. Dann verwendet es einen Algorithmus namens Eugene W. Der Algorithmus von Myersstellt die Mindestanzahl von Änderungen fest, die von der alten Liste vorgenommen werden müssen, um die neue Liste zu generieren.
Sobald DiffUtil
herausgefunden hat, was sich geändert hat, kann RecyclerView
diese Informationen verwenden, um nur die Elemente zu aktualisieren, die hinzugefügt, entfernt oder verschoben wurden. Das ist wesentlich effizienter als das Wiederholen der gesamten Liste.
In dieser Aufgabe führen Sie ein Upgrade von SleepNightAdapter
durch, um DiffUtil
zu verwenden, um RecyclerView
für Datenänderungen zu optimieren.
Schritt 1: SleepNightDiffCallback implementieren
Erweitere DiffUtil.ItemCallback
, um die Funktionalität der DiffUtil
-Klasse zu nutzen.
- Öffnen Sie
SleepNightAdapter.kt
. - Erstellen Sie unterhalb der vollständigen Klassendefinition für
SleepNightAdapter
eine neue übergeordnete Klasse namensSleepNightDiffCallback
, dieDiffUtil.ItemCallback
erweitert. ÜbergibSleepNight
als generischen Parameter.
class SleepNightDiffCallback : DiffUtil.ItemCallback<SleepNight>() {
}
- Fügen Sie den Cursor in den Klassennamen
SleepNightDiffCallback
ein. - Drücken Sie
Alt+Enter
(Option+Enter
auf dem Mac) und wählen Sie Mitglieder implementieren aus. - Ein Dialogfeld wird geöffnet. Klicken Sie mit der linken Maustaste, um die Methoden
areItemsTheSame()
undareContentsTheSame()
auszuwählen, und klicken Sie dann auf OK.
Damit werden für die beiden Methoden Stubs inSleepNightDiffCallback
generiert, wie unten dargestellt.DiffUtil
verwendet diese beiden Methoden, um herauszufinden, wie sich die Liste und die Artikel verändert haben.
override fun areItemsTheSame(oldItem: SleepNight, newItem: SleepNight): Boolean {
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
}
override fun areContentsTheSame(oldItem: SleepNight, newItem: SleepNight): Boolean {
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
}
- Ersetzen Sie
TODO
inareItemsTheSame()
durch Code, der prüft, ob die beiden übergebenenSleepNight
-ElementeoldItem
undnewItem
identisch sind. Wenn die Artikel denselbennightId
haben, handelt es sich um denselben Artikel. Geben Sietrue
zurück. Andernfalls wirdfalse
zurückgegeben.DiffUtil
verwendet diesen Test, um festzustellen, ob ein Element hinzugefügt, entfernt oder verschoben wurde.
override fun areItemsTheSame(oldItem: SleepNight, newItem: SleepNight): Boolean {
return oldItem.nightId == newItem.nightId
}
- Prüfen Sie, ob
oldItem
undnewItem
inareContentsTheSame()
dieselben Daten enthalten. Diese Gleichheitsüberprüfung prüft alle Felder, daSleepNight
eine Datenklasse ist. MitData
-Klassen werdenequals
und einige andere Methoden automatisch definiert. Wenn es Unterschiede zwischenoldItem
undnewItem
gibt, informiert dieser CodeDiffUtil
darüber, dass das Element aktualisiert wurde.
override fun areContentsTheSame(oldItem: SleepNight, newItem: SleepNight): Boolean {
return oldItem == newItem
}
Es ist ein gängiges Muster, ein RecyclerView
zur Anzeige einer sich ändernden Liste zu verwenden. RecyclerView
stellt die Adapterklasse ListAdapter
bereit, mit der Sie einen RecyclerView
-Adapter erstellen können, der von einer Liste unterstützt wird.
ListAdapter
erfasst die Liste und informiert den Adapter bei der Aktualisierung.
Schritt 1: Adapter ändern, um ListAdapter zu erweitern
- Ändern Sie in der Datei
SleepNightAdapter.kt
die Klassensignatur vonSleepNightAdapter
, umListAdapter
zu erweitern. - Importieren Sie den
androidx.recyclerview.widget.ListAdapter
, wenn Sie dazu aufgefordert werden. - Fügen Sie
SleepNight
als erstes Argument vorListAdapter
hinzu (vorSleepNightAdapter.ViewHolder
). - Fügen Sie
SleepNightDiffCallback()
als Parameter zum Konstruktor hinzu. DasListAdapter
verwendet dieses Feld, um herauszufinden, was sich in der Liste geändert hat. Die fertigeSleepNightAdapter
-Unterschrift sollte so aussehen:
class SleepNightAdapter : ListAdapter<SleepNight, SleepNightAdapter.ViewHolder>(SleepNightDiffCallback()) {
- Löschen Sie innerhalb der Klasse
SleepNightAdapter
das Felddata
, einschließlich des Setters. Du brauchst sie nicht mehr, weilListAdapter
die Liste für dich verwaltet. - Lösche die Überschreibung von
getItemCount()
, daListAdapter
diese Methode für dich implementiert. - Ändern Sie die Variable
item
, um den Fehler inonBindViewHolder()
zu entfernen. Anstattdata
zu erhalten, rufen Sie eineitem
-Methode auf, die vonListAdapter
bereitgestellt wird.
val item = getItem(position)
Schritt 2: Liste mit „listList()“ aktualisieren
Der Code muss ListAdapter
mitteilen, wenn eine geänderte Liste verfügbar ist. ListAdapter
bietet eine Methode namens submitList()
, mit der ListAdapter
informiert wird, dass eine neue Version der Liste verfügbar ist. Beim Aufrufen dieser Methode vergleicht ListAdapter
die neue Liste mit der alten Liste und erkennt Elemente, die hinzugefügt, entfernt, verschoben oder geändert wurden. Anschließend werden durch ListAdapter
die von RecyclerView
angezeigten Elemente aktualisiert.
- Öffnen Sie
SleepTrackerFragment.kt
. - Suchen Sie im
onCreateView()
im Beobachtungsserver untersleepTrackerViewModel
nach dem Fehler, auf den die gelöschtedata
-Variable verweist. - Ersetzen Sie
adapter.data = it
durch einen Aufruf vonadapter.submitList(it)
. Der aktualisierte Code wird unten dargestellt.
sleepTrackerViewModel.nights.observe(viewLifecycleOwner, Observer {
it?.let {
adapter.submitList(it)
}
})
- Führe deine App aus. Sie wird schneller ausgeführt, wenn deine Liste klein ist.
Bei dieser Aufgabe verwenden Sie dasselbe Verfahren wie in vorherigen Codelabs, um die Datenbindung einzurichten. Außerdem vermeiden Sie Aufrufe von findViewById()
.
Schritt 1: Datenbindung zur Layoutdatei hinzufügen
- Öffne die Layoutdatei
list_item_sleep_night.xml
auf dem Tab Text. - Setze den Cursor auf das Tag
ConstraintLayout
und drückeAlt+Enter
(Option+Enter
auf einem Mac). Das Intent-Menü (das Schnellmenü) wird geöffnet. - Wählen Sie In Datenbindungslayout konvertieren aus. Dadurch wird das Layout in
<layout>
eingeschlossen und darin wird ein<data>
-Tag eingefügt. - Scrollen Sie bei Bedarf zurück nach oben und definieren Sie im
<data>
-Tag eine Variable mit dem Namensleep
. - Machen Sie seinen
type
zum voll qualifizierten Namen vonSleepNight
,com.example.android.trackmysleepquality.database.SleepNight
. Das fertige<data>
-Tag sollte wie unten gezeigt aussehen.
<data>
<variable
name="sleep"
type="com.example.android.trackmysleepquality.database.SleepNight"/>
</data>
- Wenn Sie die Erstellung des Objekts
Binding
erzwingen möchten, wählen Sie Build > Clean Project und dann Build > Rebuild Project aus. Falls weiterhin Probleme auftreten, wählen Sie Datei > Caches entwerten/Neu starten aus. Das BindungsobjektListItemSleepNightBinding
sowie der zugehörige Code werden den generierten Dateien des Projekts hinzugefügt.
Schritt 2: Artikellayout mithilfe von Datenbindung erweitern
- Öffnen Sie
SleepNightAdapter.kt
. - Suche in der Klasse
ViewHolder
nach der Methodefrom()
. - Löschen Sie die Deklaration der Variable
view
.
Code zum Löschen:
val view = layoutInflater
.inflate(R.layout.list_item_sleep_night, parent, false)
- Legen Sie dort, wo die
view
-Variable war, eine neue Variable mit dem Namenbinding
fest, die das BindungsobjektListItemSleepNightBinding
aufgebläht. Führen Sie den erforderlichen Import des Bindungsobjekts aus.
val binding =
ListItemSleepNightBinding.inflate(layoutInflater, parent, false)
- Geben Sie am Ende der Funktion
binding
zurück, anstattview
zurückzugeben.
return ViewHolder(binding)
- Fügen Sie den Cursor über das Wort
binding
, um den Fehler zu beheben. Drücken SieAlt+Enter
(Option+Enter
auf einem Mac), um das Intent-Menü zu öffnen.
- Wählen Sie Parameter „'itemView'“ des primären Konstruktors der Klasse „'ViewHolder'“ auf 'ListItemSleepNightBindung' aus. Aktualisiert den Parametertyp der Klasse
ViewHolder
.
- Scrollen Sie nach oben zur Klassendefinition von
ViewHolder
, um die Änderung in der Signatur zu sehen. Sie sehen eine Fehlermeldung füritemView
, weil SieitemView
infrom()
in der Methodefrom()
geändert haben.
Klicken Sie in der KlassendefinitionViewHolder
mit der rechten Maustaste auf eine der Vorkommen initemView
und wählen Sie Refaktorieren > Umbenennen aus. Ändern Sie den Namen inbinding
. - Stelle dem Konstruktor-Parameter
binding
val
zu, um sie als Property festzulegen. - Ändern Sie beim Aufruf der übergeordneten Klasse
RecyclerView.ViewHolder
den Parameter vonbinding
inbinding.root
. Sie müssen eineView
übergeben.binding.root
ist die Stamm-ConstraintLayout
in Ihrem Artikellayout. - Die fertige Kursdeklaration sollte so aussehen:
class ViewHolder private constructor(val binding: ListItemSleepNightBinding) : RecyclerView.ViewHolder(binding.root){
Außerdem wird eine Fehlermeldung für die Aufrufe von findViewById()
angezeigt. Dieses Problem müssen Sie als Nächstes beheben.
Schritt 3: „findViewById()“ ersetzen
Du kannst jetzt die Properties sleepLength
, quality
und qualityImage
aktualisieren, um das Objekt binding
anstelle von findViewById()
zu verwenden.
- Ändere die Initialisierungen von
sleepLength
,qualityString
undqualityImage
, um die Ansichten desbinding
-Objekts zu verwenden, wie unten dargestellt. Danach sollten keine Fehler mehr im Code angezeigt werden.
val sleepLength: TextView = binding.sleepLength
val quality: TextView = binding.qualityString
val qualityImage: ImageView = binding.qualityImage
Wenn das Bindungsobjekt vorhanden ist, müssen Sie die Properties sleepLength
, quality
und qualityImage
nicht mehr definieren. DataBinding
speichert die Lookups im Cache. Daher müssen diese Properties nicht deklariert werden.
- Klicken Sie mit der rechten Maustaste auf die Namen von Properties
sleepLength
,quality
undqualityImage
. Wählen Sie Refaktorieren &enden; Inline aus oder drücken SieControl+Command+N
(Option+Command+N
auf dem Mac). - Führen Sie die Anwendung aus. Möglicherweise müssen Sie das Projekt bereinigen und gegebenenfalls neu erstellen.
In dieser Aufgabe führen Sie ein Upgrade Ihrer App für die Datenbindung mit Bindungsadaptern aus, um die Daten in Ihren Ansichten festzulegen.
In einem vorherigen Codelab haben Sie die Klasse Transformations
verwendet, um LiveData
zu erstellen und formatierte Strings zu generieren, die in Textansichten angezeigt werden. Wenn Sie jedoch verschiedene Typen oder komplexe Typen binden müssen, können Sie Bindungsadapter bereitstellen, um die Datenbindung bei der Verwendung dieser Typen zu unterstützen. Bindungsadapter sind Adapter, die Ihre Daten so anpassen, dass sie mithilfe der Datenbindung eine Ansicht, z. B. Text oder ein Bild, binden können.
Sie implementieren drei Bindungsadapter, einen für das Bild und einen für jedes Textfeld. Definieren Sie dazu einen Bindungsadapter: Sie definieren eine Methode, die ein Element und eine Ansicht verwendet und mit @BindingAdapter
annotiert. Im Text der Methode implementieren Sie die Transformation. In Kotlin können Sie einen Bindungsadapter als Erweiterungsfunktion in die Ansichtsklasse schreiben, die die Daten empfängt.
Schritt 1: Bindungsadapter erstellen
Beachten Sie, dass Sie in diesem Schritt mehrere Kurse importieren müssen, die nicht einzeln aufgerufen werden.
- Öffnen Sie
SleepNightAdapater.kt
. - Suchen Sie in der Klasse
ViewHolder
die Methodebind()
und erinnern Sie sich daran, was diese Methode bewirkt. Sie nehmen stattdessen den Code, der die Werte fürbinding.sleepLength
,binding.quality
undbinding.qualityImage
berechnet, und verwenden ihn im Adapter. Wir empfehlen, den Code vorerst unverändert zu lassen. - Erstellen und öffnen Sie im Paket
sleeptracker
eine Datei mit dem NamenBindingUtils.kt
. - Deklarieren Sie in
TextView
die ErweiterungsfunktionsetSleepDurationFormatted
und übergeben SieSleepNight
. Diese Funktion ist dein Adapter zum Berechnen und Formatieren der Schlafdauer.
fun TextView.setSleepDurationFormatted(item: SleepNight) {}
- Binden Sie die Daten im Anfragetext von
setSleepDurationFormatted
an die Ansicht wie inViewHolder.bind()
. RufeconvertDurationToFormatted()
auf und lege danntext
fürTextView
auf den formatierten Text fest. Weil dies eine Erweiterungsfunktion unterTextView
ist, kannst du direkt auf die Propertytext
zugreifen.
text = convertDurationToFormatted(item.startTimeMilli, item.endTimeMilli, context.resources)
- Kennzeichnen Sie die Funktion mit
@BindingAdapter
, um die Datenbindung über diesen Bindungsadapter zu informieren. - Diese Funktion ist der Adapter für das Attribut
sleepDurationFormatted
. Übergeben Sie dahersleepDurationFormatted
als Argument an@BindingAdapter
.
@BindingAdapter("sleepDurationFormatted")
- Mit dem zweiten Adapter wird die Schlafqualität basierend auf dem Wert in einem
SleepNight
-Objekt festgelegt. Erstelle eine Erweiterungsfunktion namenssetSleepQualityString()
aufTextView
und übergib einSleepNight
-Element. - Binden Sie die Daten im Anfragetext an die Ansicht in
ViewHolder.bind()
an. Rufen SieconvertNumericQualityToString
auf und legen Sie dentext
fest. - Funktion mit
@BindingAdapter("sleepQualityString")
annotieren
@BindingAdapter("sleepQualityString")
fun TextView.setSleepQualityString(item: SleepNight) {
text = convertNumericQualityToString(item.sleepQuality, context.resources)
}
- Mit dem dritten Bindungsadapter wird das Bild in einer Bildansicht festgelegt. Erstellen Sie die Erweiterungsfunktion in
ImageView
, rufen SiesetSleepImage
auf und verwenden Sie den Code ausViewHolder.bind()
, wie unten dargestellt.
@BindingAdapter("sleepImage")
fun ImageView.setSleepImage(item: SleepNight) {
setImageResource(when (item.sleepQuality) {
0 -> R.drawable.ic_sleep_0
1 -> R.drawable.ic_sleep_1
2 -> R.drawable.ic_sleep_2
3 -> R.drawable.ic_sleep_3
4 -> R.drawable.ic_sleep_4
5 -> R.drawable.ic_sleep_5
else -> R.drawable.ic_sleep_active
})
}
Schritt 2: SleepNightAdapter aktualisieren
- Öffnen Sie
SleepNightAdapter.kt
. - Löschen Sie alles in der Methode
bind()
, da Sie jetzt die Datenbindung und die neuen Adapter verwenden können.
fun bind(item: SleepNight) {
}
- Weisen Sie
item
inbind()
den Schlaf zu, da Sie das Bindungsobjekt über Ihr neuesSleepNight
-Element informieren müssen.
binding.sleep = item
- Fügen Sie unter dieser Zeile
binding.executePendingBindings()
hinzu. Dieser Aufruf ist eine Optimierung, bei der die Datenbindung aufgefordert wird, alle ausstehenden Bindungen sofort auszuführen. Es wird immer empfohlen,executePendingBindings()
aufzurufen, wenn Sie Bindungsadapter in einemRecyclerView
-Element verwenden. Dies kann die Größe der Aufrufe leicht beschleunigen.
binding.executePendingBindings()
Schritt 3: Bindungen zum XML-Layout hinzufügen
- Öffnen Sie
list_item_sleep_night.xml
. - Fügen Sie in
ImageView
eineapp
-Property mit demselben Namen wie der Bindungsadapter hinzu, mit dem das Bild festgelegt wird. Übergeben Sie die Variablesleep
wie unten gezeigt.
Diese Property erstellt die Verbindung zwischen der Ansicht und dem Bindungsobjekt über den Adapter. Wenn aufsleepImage
verwiesen wird, werden die Daten vonSleepNight
vom Adapter angepasst.
app:sleepImage="@{sleep}"
- Verfahren Sie ebenso mit den Textansichten "
sleep_length
" und "quality_string
". WennsleepDurationFormatted
odersleepQualityString
referenziert werden, passen die Adapter die Daten vonSleepNight
an.
app:sleepDurationFormatted="@{sleep}"
app:sleepQualityString="@{sleep}"
- Führen Sie Ihre App aus. Sie funktioniert genau wie vorher. Die Bindungsadapter übernehmen die Formatierung und die Aktualisierung von Ansichten, wenn sich die Daten ändern. Dadurch wird
ViewHolder
vereinfacht und der Code wesentlich besser strukturiert als zuvor.
Du hast für die letzten paar Übungen dieselbe Liste angezeigt. Wir zeigen Ihnen, dass Sie mit der Adapter
-Oberfläche Ihren Code auf unterschiedliche Weise erstellen können. Je komplexer Ihr Code, desto wichtiger wird es, ihn zu entwerfen. In Produktions-Apps werden diese und andere Muster mit RecyclerView
verwendet. Alle Muster funktionieren und jedes hat seine Vorteile. Für welche Sie sich entscheiden, hängt davon ab, was Sie erstellen.
Glückwunsch! Bist du auf dem richtigen Weg, dein Wissen über RecyclerView
auf Android zu beherrschen?
Android Studio-Projekt: RecyclerViewDiffUtilDataBindung
DiffUtil
:
RecyclerView
hat eine Klasse namensDiffUtil
, mit der die Unterschiede zwischen zwei Listen berechnet werden.DiffUtil
hat eine Klasse namensItemCallBack
, die Sie verlängern, um den Unterschied zwischen den beiden Listen zu ermitteln.- In der Klasse
ItemCallback
musst du die MethodenareItemsTheSame()
undareContentsTheSame()
überschreiben.
ListAdapter
:
- Wenn Sie Listen kostenlos verwalten möchten, verwenden Sie die Klasse
ListAdapter
anstelle vonRecyclerView.Adapter
. Wenn SieListAdapter
verwenden, müssen Sie jedoch Ihren eigenen Adapter für andere Layouts erstellen. In diesem Codelab erfahren Sie, wie das geht. - Wenn Sie das Intent-Menü in Android Studio öffnen möchten, platzieren Sie den Cursor auf einem Code-Element und drücken Sie
Alt+Enter
(Option+Enter
auf dem Mac). Dieses Menü ist besonders nützlich für die Refaktorierung von Code und die Erstellung von Stubs für Implementierungsmethoden. Das Menü ist kontextabhängig. Sie müssen den Cursor also genau platzieren, um das richtige Menü zu erhalten.
Datenbindung:
- Datenbindung im Elementlayout verwenden, um Daten an die Ansichten zu binden.
Bindungsadapter:
- Du hast zuvor
Transformations
verwendet, um Strings aus Daten zu erstellen. Wenn Sie Daten verschiedener oder komplexer Typen binden müssen, stellen Sie Bindungsadapter bereit, um die Datenbindung zu verwenden. - Wenn Sie einen Bindungsadapter deklarieren möchten, müssen Sie eine Methode definieren, die ein Element und eine Ansicht verwendet und mit
@BindingAdapter
die Annotation annotiert. In Kotlin können Sie den Bindungsadapter als Erweiterungsfunktion imView
schreiben. Geben Sie den Namen der Eigenschaft ein, die der Adapter anpasst. Beispiel:
@BindingAdapter("sleepDurationFormatted")
- Legen Sie im XML-Layout eine
app
-Property mit demselben Namen wie der Bindungsadapter fest. eine Variable mit den Daten übergeben. Beispiel:
.app:sleepDurationFormatted="@{sleep}"
Udacity-Kurse:
Android-Entwicklerdokumentation:
- Liste mit RecyclerView erstellen
RecyclerView
DiffUtil
- Datenbindungsbibliothek
- Bindungsadapter
notifyDataSetChanged()
Transformations
Weitere Informationen:
In diesem Abschnitt werden mögliche Hausaufgaben für Schüler oder Studenten aufgeführt, die an diesem von einem Kursleiter geleiteten Codelab arbeiten. Die Lehrkraft kann Folgendes tun:
- Bei Bedarf können Sie die entsprechenden Aufgaben zuweisen.
- Schülern mitteilen, wie sie Aufgaben für die Aufgabe abgeben
- Benoten Sie die Hausaufgaben.
Lehrkräfte können diese Vorschläge so oft oder so oft verwenden, wie sie möchten. anderen Aufgaben können sie nach Belieben zugewiesen werden.
Wenn Sie alleine an diesem Codelab arbeiten, können Sie Ihr Wissen mit diesen Hausaufgaben testen.
Diese Fragen beantworten
Frage 1
Was benötigen Sie, um DiffUtil
verwenden zu können? Wählen Sie alle zutreffenden Antworten aus.
▢ Erweitern Sie die ItemCallBack
-Klasse.
▢ Überschreibe areItemsTheSame()
.
▢ Überschreibe areContentsTheSame()
.
▢ Mit Datenbindung lassen sich die Unterschiede zwischen einzelnen Elementen verfolgen.
Frage 2
Welche der folgenden Aussagen über Bindungsadapter sind richtig?
▢ Ein Bindungsadapter ist eine Funktion, die mit @BindingAdapter
kommentiert wird.
▢ Mit einem Bindungsadapter können Sie die Datenformatierung vom Inhaber der Ansicht trennen.
▢ Sie müssen ein RecyclerViewAdapter
-Element verwenden, wenn Sie Bindungsadapter verwenden möchten.
▢ Bindungsadapter sind eine gute Lösung, wenn Sie komplexe Daten umwandeln müssen.
Frage 3
Wann sollten Sie Transformations
anstelle eines Bindungsadapters verwenden? Wählen Sie alle zutreffenden Antworten aus.
▢.
▢ Sie formatieren einen String.
▢ Ihre Liste ist sehr lang.
▢ Der Messwert"ViewHolder
"enthält nur einen Aufruf.
Beginnen Sie mit der nächsten Lektion: