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 wird zusammengefasst, wie Sie ViewModel
und Fragmente zusammen verwenden, um die Navigation zu implementieren. Denken Sie daran, dass die Logik von when in ViewModel
platziert werden soll, die Pfade jedoch in den Fragmenten und der Navigationsdatei definiert werden. Dazu verwenden Sie Ansichtsmodelle, Fragmente, LiveData
und Beobachter.
Am Ende des Codelabs wird eine clevere Methode zum Erfassen von Schaltflächenstatus mit minimalem Code gezeigt, sodass jede Schaltfläche nur dann aktiviert und anklickbar ist, wenn es für den Nutzer sinnvoll ist, darauf zu tippen.
Was Sie bereits wissen sollten
Sie sollten mit Folgendem vertraut sein:
- Eine einfache Benutzeroberfläche mit einer Aktivität, Fragmenten und Ansichten erstellen.
- Zwischen Fragmenten wechseln und
safeArgs
verwenden, um Daten zwischen Fragmenten zu übergeben. - Modelle, Modell-Factories, Transformationen und
LiveData
sowie deren Beobachter ansehen - Wie Sie eine
Room
-Datenbank erstellen, ein Datenzugriffsobjekt (DAO) erstellen und Entitäten definieren. - Verwendung von Coroutinen für Datenbankinteraktionen und andere zeitaufwendige Aufgaben
Lerninhalte
- So aktualisierst du einen vorhandenen Schlafqualitätsdatensatz in der Datenbank.
- So verwenden Sie
LiveData
, um Schaltflächenstatus zu erfassen. - So wird eine Snackbar als Reaktion auf ein Ereignis angezeigt.
Aufgaben
- Erweitern Sie die App „TrackMySleepQuality“, um eine Qualitätsbewertung zu erfassen, die Bewertung der Datenbank hinzuzufügen und das Ergebnis anzuzeigen.
- Verwenden Sie
LiveData
, um die Anzeige einer Snackbar auszulösen. - Mit
LiveData
können Sie Schaltflächen aktivieren und deaktivieren.
In diesem Codelab erstellen Sie die Aufzeichnung der Schlafqualität und die endgültige Benutzeroberfläche der App „TrackMySleepQuality“.
Die App hat zwei Bildschirme, die durch Fragmente dargestellt werden, wie in der Abbildung unten zu sehen ist.
Auf dem ersten Bildschirm links befinden sich Schaltflächen zum Starten und Beenden des Trackings. Auf dem Bildschirm werden alle 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 rechts können Sie eine Bewertung der Schlafqualität auswählen. In der App wird die Bewertung numerisch dargestellt. Zu Entwicklungszwecken werden in der App sowohl die Gesichtssymbole als auch ihre numerischen Entsprechungen angezeigt.
Der Ablauf für den Nutzer sieht so aus:
- Der Nutzer öffnet die App und sieht den Bildschirm für die Schlafanalyse.
- Der Nutzer tippt auf die Schaltfläche Starten. Die Startzeit wird aufgezeichnet und angezeigt. Die Schaltfläche Starten ist deaktiviert und die Schaltfläche Beenden ist aktiviert.
- Der Nutzer tippt auf die Schaltfläche Stopp. Dadurch wird die Endzeit aufgezeichnet und der Bildschirm „Schlafqualität“ geöffnet.
- Der Nutzer wählt ein Symbol für die Schlafqualität aus. Der Bildschirm wird geschlossen und auf dem Tracking-Bildschirm werden die Endzeit des Schlafs und die Schlafqualität angezeigt. Die Schaltfläche Beenden ist deaktiviert und die Schaltfläche Starten ist aktiviert. Die App ist bereit für eine weitere Nacht.
- Die Schaltfläche Löschen ist immer dann aktiviert, wenn Daten in der Datenbank vorhanden sind. Wenn der Nutzer auf die Schaltfläche Löschen tippt, werden alle seine Daten unwiderruflich gelöscht. Es wird keine Bestätigungsmeldung angezeigt.
Diese App verwendet eine vereinfachte Architektur, wie unten im Kontext der vollständigen Architektur dargestellt. Die App verwendet nur die folgenden Komponenten:
- UI-Controller
- Modell und
LiveData
ansehen - Eine Room-Datenbank
In diesem Codelab wird davon ausgegangen, dass Sie wissen, wie Sie die Navigation mit Fragmenten und der Navigationsdatei implementieren. Damit Sie nicht so viel Arbeit haben, wird ein Großteil dieses Codes bereitgestellt.
Schritt 1: Code prüfen
- Fahren Sie mit Ihrem eigenen Code aus dem letzten Codelab fort oder laden Sie den Starter-Code herunter.
- Sehen Sie sich im Starter-Code die
SleepQualityFragment
an. Diese Klasse instanziiert das Layout, ruft die Anwendung ab und gibtbinding.root
zurück. - Öffnen Sie navigation.xml im Designeditor. Sie sehen, dass es einen Navigationspfad von
SleepTrackerFragment
nachSleepQualityFragment
und zurück vonSleepQualityFragment
nachSleepTrackerFragment
gibt. - Sehen Sie sich den Code für navigation.xml an. Achten Sie insbesondere auf die
<argument>
mit dem NamensleepNightKey
.
Wenn der Nutzer vonSleepTrackerFragment
zuSleepQualityFragment,
wechselt, übergibt die App einensleepNightKey
anSleepQualityFragment
für die Nacht, die aktualisiert werden muss.
Schritt 2: Navigation für die Schlafanalyse hinzufügen
Der Navigationsgraph enthält bereits die Pfade von SleepTrackerFragment
zu SleepQualityFragment
und zurück. Die Click-Handler, die die Navigation von einem Fragment zum nächsten implementieren, sind jedoch noch nicht codiert. Fügen Sie diesen Code jetzt in ViewModel
ein.
Im Click-Handler legen Sie eine LiveData
fest, die sich ändert, wenn die App zu einem anderen Ziel navigieren soll. Das Fragment berücksichtigt diese LiveData
. Wenn sich die Daten ändern, navigiert das Fragment zum Ziel und teilt dem ViewModel mit, dass es fertig ist. Dadurch wird die Statusvariable zurückgesetzt.
- Öffnen Sie
SleepTrackerViewModel
. Sie müssen eine Navigation hinzufügen, damit die App zurSleepQualityFragment
weitergeleitet wird, wenn der Nutzer auf die Schaltfläche Stop tippt, um eine Qualitätsbewertung zu erfassen. - Erstellen Sie in
SleepTrackerViewModel
eineLiveData
, die sich ändert, wenn die App zurSleepQualityFragment
navigieren soll. Verwenden Sie die Kapselung, um nur eine abrufbare Version vonLiveData
fürViewModel
verfügbar zu machen.
Sie können diesen Code an einer beliebigen Stelle auf der obersten Ebene des Klassenrumpfs einfügen.
private val _navigateToSleepQuality = MutableLiveData<SleepNight>()
val navigateToSleepQuality: LiveData<SleepNight>
get() = _navigateToSleepQuality
- Fügen Sie eine
doneNavigating()
-Funktion hinzu, die die Variable zurücksetzt, die die Navigation auslöst.
fun doneNavigating() {
_navigateToSleepQuality.value = null
}
- Lösen Sie im Click-Handler für die Schaltfläche Beenden
onStopTracking()
die Navigation zuSleepQualityFragment
aus. Legen Sie die Variable _navigateToSleepQuality
am Ende der Funktion als letztes Element imlaunch{}
-Block fest. Diese Variable ist aufnight
festgelegt. Wenn diese Variable einen Wert hat, wird in der App zuSleepQualityFragment
navigiert und die Nacht wird übergeben.
_navigateToSleepQuality.value = oldNight
- Das
SleepTrackerFragment
muss _navigateToSleepQuality
beobachten, damit die App weiß, wann sie die Navigation starten soll. Fügen Sie inSleepTrackerFragment
inonCreateView()
einen Beobachter fürnavigateToSleepQuality()
hinzu. Der Import für diese Funktion ist mehrdeutig. Sie müssenandroidx.lifecycle.Observer
.
importieren.
sleepTrackerViewModel.navigateToSleepQuality.observe(this, Observer {
})
- Rufen Sie im Observer-Block die ID der aktuellen Nacht ab und übergeben Sie sie. Rufen Sie dann
doneNavigating()
auf. Wenn Ihr Import mehrdeutig ist, importieren Sieandroidx.navigation.fragment.findNavController
.
night ->
night?.let {
this.findNavController().navigate(
SleepTrackerFragmentDirections
.actionSleepTrackerFragmentToSleepQualityFragment(night.nightId))
sleepTrackerViewModel.doneNavigating()
}
- Erstelle und führe die App aus. Tippe auf Start und dann auf Stop. Dadurch gelangst du zum Bildschirm
SleepQualityFragment
. Verwenden Sie die Systemschaltfläche „Zurück“, um zurückzukehren.
In dieser Aufgabe zeichnen Sie die Schlafqualität auf und kehren zum Fragment für die Schlafanalyse zurück. Das Display sollte automatisch aktualisiert werden, um dem Nutzer den aktualisierten Wert anzuzeigen. Sie müssen ein ViewModel
und ein ViewModelFactory
erstellen und das SleepQualityFragment
aktualisieren.
Schritt 1: ViewModel und ViewModelFactory erstellen
- Erstelle oder öffne im Paket
sleepquality
die Datei SleepQualityViewModel.kt. - Erstellen Sie eine
SleepQualityViewModel
-Klasse, die einesleepNightKey
und eine Datenbank als Argumente akzeptiert. Genau wie beimSleepTrackerViewModel
müssen Sie dasdatabase
aus der Factory übergeben. Außerdem müssen Sie diesleepNightKey
aus der Navigation übergeben.
class SleepQualityViewModel(
private val sleepNightKey: Long = 0L,
val database: SleepDatabaseDao) : ViewModel() {
}
- Definieren Sie in der
SleepQualityViewModel
-Klasse eineJob
und eineuiScope
und überschreiben SieonCleared()
.
private val viewModelJob = Job()
private val uiScope = CoroutineScope(Dispatchers.Main + viewModelJob)
override fun onCleared() {
super.onCleared()
viewModelJob.cancel()
}
- Wenn Sie mit demselben Muster wie oben zur
SleepTrackerFragment
zurückkehren möchten, deklarieren Sie_navigateToSleepTracker
. Implementieren SienavigateToSleepTracker
unddoneNavigating()
.
private val _navigateToSleepTracker = MutableLiveData<Boolean?>()
val navigateToSleepTracker: LiveData<Boolean?>
get() = _navigateToSleepTracker
fun doneNavigating() {
_navigateToSleepTracker.value = null
}
- Erstelle einen Click-Handler,
onSetSleepQuality()
, für alle Bilder zur Schlafqualität.
Verwende dasselbe Coroutine-Muster wie im vorherigen Codelab:
- Starten Sie eine Coroutine in
uiScope
und wechseln Sie zum I/O-Dispatcher. tonight
über diesleepNightKey
abrufen- Schlafqualität festlegen
- Aktualisieren Sie die Datenbank.
- Navigation auslösen
Im folgenden Beispielcode wird die gesamte Arbeit im Klick-Handler erledigt, anstatt den Datenbankvorgang im anderen Kontext auszulagern.
fun onSetSleepQuality(quality: Int) {
uiScope.launch {
// IO is a thread pool for running operations that access the disk, such as
// our Room database.
withContext(Dispatchers.IO) {
val tonight = database.get(sleepNightKey) ?: return@withContext
tonight.sleepQuality = quality
database.update(tonight)
}
// Setting this state variable to true will alert the observer and trigger navigation.
_navigateToSleepTracker.value = true
}
}
- Erstellen oder öffnen Sie im Paket
sleepquality
die DateiSleepQualityViewModelFactory.kt
und fügen Sie die KlasseSleepQualityViewModelFactory
wie unten gezeigt hinzu. Diese Klasse verwendet eine Version desselben Boilerplate-Codes, den Sie bereits kennen. Sehen Sie sich den Code an, bevor Sie fortfahren.
class SleepQualityViewModelFactory(
private val sleepNightKey: Long,
private val dataSource: SleepDatabaseDao) : ViewModelProvider.Factory {
@Suppress("unchecked_cast")
override fun <T : ViewModel?> create(modelClass: Class<T>): T {
if (modelClass.isAssignableFrom(SleepQualityViewModel::class.java)) {
return SleepQualityViewModel(sleepNightKey, dataSource) as T
}
throw IllegalArgumentException("Unknown ViewModel class")
}
}
Schritt 2: SleepQualityFragment aktualisieren
- Öffnen Sie
SleepQualityFragment.kt
. - In
onCreateView()
müssen Sie nach dem Abrufen vonapplication
diearguments
abrufen, die mit der Navigation geliefert wurde. Diese Argumente befinden sich inSleepQualityFragmentArgs
. Sie müssen sie aus dem Bundle extrahieren.
val arguments = SleepQualityFragmentArgs.fromBundle(arguments!!)
- Rufen Sie als Nächstes die
dataSource
ab.
val dataSource = SleepDatabase.getInstance(application).sleepDatabaseDao
- Erstellen Sie eine Factory und übergeben Sie
dataSource
undsleepNightKey
.
val viewModelFactory = SleepQualityViewModelFactory(arguments.sleepNightKey, dataSource)
ViewModel
-Referenz abrufen
val sleepQualityViewModel =
ViewModelProviders.of(
this, viewModelFactory).get(SleepQualityViewModel::class.java)
- Fügen Sie
ViewModel
dem Bindungsobjekt hinzu. Wenn Sie einen Fehler mit dem Bindungsobjekt sehen, ignorieren Sie ihn vorerst.
binding.sleepQualityViewModel = sleepQualityViewModel
- Fügen Sie den Beobachter hinzu. Importieren Sie bei Aufforderung
androidx.lifecycle.Observer
.
sleepQualityViewModel.navigateToSleepTracker.observe(this, Observer {
if (it == true) { // Observed state is true.
this.findNavController().navigate(
SleepQualityFragmentDirections.actionSleepQualityFragmentToSleepTrackerFragment())
sleepQualityViewModel.doneNavigating()
}
})
Schritt 3: Layoutdatei aktualisieren und App ausführen
- Öffnen Sie die Layoutdatei
fragment_sleep_quality.xml
. Fügen Sie im Block<data>
eine Variable fürSleepQualityViewModel
hinzu.
<data>
<variable
name="sleepQualityViewModel"
type="com.example.android.trackmysleepquality.sleepquality.SleepQualityViewModel" />
</data>
- Fügen Sie für jedes der sechs Bilder zur Schlafqualität einen Click-Handler wie den unten stehenden hinzu. Ordne dem Bild die Qualitätsbewertung zu.
android:onClick="@{() -> sleepQualityViewModel.onSetSleepQuality(5)}"
- Bereinigen Sie Ihr Projekt und erstellen Sie es neu. Dadurch sollten alle Fehler mit dem Bindungsobjekt behoben werden. Andernfalls leeren Sie den Cache (File > Invalidate Caches / Restart) und erstellen Sie Ihre App neu.
Glückwunsch! Sie haben gerade eine vollständige Room
-Datenbank-App mit Coroutinen erstellt.
Ihre App funktioniert jetzt einwandfrei. Der Nutzer kann beliebig oft auf Starten und Beenden tippen. Wenn der Nutzer auf Beenden tippt, kann er eine Schlafqualität eingeben. Wenn der Nutzer auf Löschen tippt, werden alle Daten im Hintergrund gelöscht. Alle Schaltflächen sind jedoch immer aktiviert und anklickbar. Das führt zwar nicht zum Absturz der App, aber Nutzer können so unvollständige Schlafnächte erstellen.
In dieser letzten Aufgabe erfahren Sie, wie Sie Transformationszuordnungen verwenden, um die Sichtbarkeit von Schaltflächen so zu verwalten, dass Nutzer nur die richtige Auswahl treffen können. Sie können eine ähnliche Methode verwenden, um eine freundliche Nachricht anzuzeigen, nachdem alle Daten gelöscht wurden.
Schritt 1: Schaltflächenstatus aktualisieren
Die Idee ist, den Schaltflächenstatus so festzulegen, dass am Anfang nur die Schaltfläche Start aktiviert ist, d. h. angeklickt werden kann.
Nachdem der Nutzer auf Start getippt hat, wird die Schaltfläche Stopp aktiviert und Start deaktiviert. Die Schaltfläche Löschen ist nur aktiviert, wenn Daten in der Datenbank vorhanden sind.
- Öffnen Sie die Layoutdatei
fragment_sleep_tracker.xml
. - Fügen Sie jedem Button die Property
android:enabled
hinzu. Die Propertyandroid:enabled
ist ein boolescher Wert, der angibt, ob die Schaltfläche aktiviert ist. Eine aktivierte Schaltfläche kann angetippt werden, eine deaktivierte nicht. Weisen Sie der Eigenschaft den Wert einer Statusvariablen zu, die Sie gleich definieren.
start_button
:
android:enabled="@{sleepTrackerViewModel.startButtonVisible}"
stop_button
:
android:enabled="@{sleepTrackerViewModel.stopButtonVisible}"
clear_button
:
android:enabled="@{sleepTrackerViewModel.clearButtonVisible}"
- Öffnen Sie
SleepTrackerViewModel
und erstellen Sie drei entsprechende Variablen. Weisen Sie jeder Variable eine Transformation zu, mit der sie getestet wird.
- Die Schaltfläche Starten sollte aktiviert sein, wenn
tonight
gleichnull
ist. - Die Schaltfläche Stoppen sollte aktiviert sein, wenn
tonight
nichtnull
ist. - Die Schaltfläche Löschen sollte nur aktiviert sein, wenn
nights
und damit die Datenbank Schlafnächte enthält.
val startButtonVisible = Transformations.map(tonight) {
it == null
}
val stopButtonVisible = Transformations.map(tonight) {
it != null
}
val clearButtonVisible = Transformations.map(nights) {
it?.isNotEmpty()
}
- Führen Sie die App aus und testen Sie die Schaltflächen.
Schritt 2: Nutzer über eine Snackbar benachrichtigen
Nachdem der Nutzer die Datenbank gelöscht hat, zeigen Sie ihm mit dem Widget Snackbar
eine Bestätigung an. Eine Snackbar bietet kurzes Feedback zu einem Vorgang in Form einer Meldung unten auf dem Bildschirm. Eine Snackbar wird nach einem Zeitlimit, nach einer Nutzerinteraktion an anderer Stelle auf dem Bildschirm oder nachdem der Nutzer die Snackbar vom Bildschirm gewischt hat, ausgeblendet.
Das Anzeigen der Snackbar ist eine UI-Aufgabe und sollte im Fragment erfolgen. Die Entscheidung, die Snackbar anzuzeigen, wird in ViewModel
getroffen. Um eine Snackbar einzurichten und auszulösen, wenn die Daten gelöscht werden, können Sie dieselbe Technik wie zum Auslösen der Navigation verwenden.
- Erstellen Sie das gekapselte Ereignis in der
SleepTrackerViewModel
.
private var _showSnackbarEvent = MutableLiveData<Boolean>()
val showSnackBarEvent: LiveData<Boolean>
get() = _showSnackbarEvent
- Implementieren Sie dann
doneShowingSnackbar()
.
fun doneShowingSnackbar() {
_showSnackbarEvent.value = false
}
- Fügen Sie in
SleepTrackerFragment
inonCreateView()
einen Beobachter hinzu:
sleepTrackerViewModel.showSnackBarEvent.observe(this, Observer { })
- Zeigen Sie innerhalb des Observer-Blocks die Snackbar an und setzen Sie das Ereignis sofort zurück.
if (it == true) { // Observed state is true.
Snackbar.make(
activity!!.findViewById(android.R.id.content),
getString(R.string.cleared_message),
Snackbar.LENGTH_SHORT // How long to display the message.
).show()
sleepTrackerViewModel.doneShowingSnackbar()
}
- Lösen Sie das Ereignis in
SleepTrackerViewModel
in der MethodeonClear()
aus. Setzen Sie dazu den Ereigniswert imlaunch
-Block auftrue
:
_showSnackbarEvent.value = true
- App erstellen und ausführen
Android Studio-Projekt: TrackMySleepQualityFinal
Die Implementierung der Analyse der Schlafqualität in dieser App ist wie das Spielen eines bekannten Musikstücks in einer neuen Tonart. Die Details ändern sich zwar, das zugrunde liegende Muster der vorherigen Codelabs in dieser Lektion bleibt jedoch gleich. Wenn Sie diese Muster kennen, können Sie viel schneller programmieren, da Sie Code aus vorhandenen Apps wiederverwenden können. Hier sind einige der Muster, die bisher in diesem Kurs verwendet wurden:
- Erstellen Sie ein
ViewModel
und einViewModelFactory
und richten Sie eine Datenquelle ein. - Navigation auslösen Um die Verantwortlichkeiten zu trennen, platzieren Sie den Klick-Handler im Viewmodel und die Navigation im Fragment.
- Verwenden Sie die Kapselung mit
LiveData
, um Statusänderungen zu verfolgen und darauf zu reagieren. - Transformationen mit
LiveData
verwenden - Singleton-Datenbank erstellen
- Koroutinen für Datenbankvorgänge einrichten
Navigation auslösen
Mögliche Navigationspfade zwischen Fragmenten werden in einer Navigationsdatei definiert. Es gibt verschiedene Möglichkeiten, die Navigation von einem Fragment zum nächsten auszulösen. Dazu gehören:
- Definieren Sie
onClick
-Handler, um die Navigation zu einem Zielfragment auszulösen. - Alternativ können Sie die Navigation von einem Fragment zum nächsten so aktivieren:
- Definieren Sie einen
LiveData
-Wert, der aufgezeichnet werden soll, wenn eine Navigation stattfinden soll. - Hängen Sie einen Observer an diesen
LiveData
-Wert an. - Ihr Code ändert diesen Wert dann immer, wenn eine Navigation ausgelöst werden muss oder abgeschlossen ist.
Das Attribut „android:enabled“ festlegen
- Das Attribut
android:enabled
wird inTextView
definiert und von allen untergeordneten Klassen, einschließlichButton
, übernommen. - Mit dem Attribut
android:enabled
wird festgelegt, ob einView
aktiviert ist. Die Bedeutung von „aktiviert“ variiert je nach Unterklasse. WennEditText
nicht aktiviert ist, kann der Nutzer beispielsweise den enthaltenen Text nicht bearbeiten. WennButton
nicht aktiviert ist, kann der Nutzer nicht auf die Schaltfläche tippen. - Das Attribut
enabled
ist nicht dasselbe wie das Attributvisibility
. - Mit Transformationszuordnungen können Sie den Wert des Attributs
enabled
von Schaltflächen basierend auf dem Status eines anderen Objekts oder einer anderen Variablen festlegen.
Weitere Punkte, die in diesem Codelab behandelt werden:
- Um Benachrichtigungen für den Nutzer auszulösen, können Sie dieselbe Methode verwenden, die Sie zum Auslösen der Navigation verwenden.
- Sie können den Nutzer mit einem
Snackbar
benachrichtigen.
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
Eine Möglichkeit, die Navigation von einem Fragment zum nächsten in Ihrer App auszulösen, besteht darin, einen LiveData
-Wert zu verwenden, um anzugeben, ob die Navigation ausgelöst werden soll.
Welche Schritte sind erforderlich, um mit einem LiveData
-Wert namens gotoBlueFragment
die Navigation vom roten zum blauen Fragment auszulösen? Wähle alle zutreffenden Optionen aus.
- Definieren Sie in der Datei
ViewModel
den WertgotoBlueFragment
fürLiveData
. - Sehen Sie sich in der Datei
RedFragment
den WertgotoBlueFragment
an. Implementieren Sie denobserve{}
-Code, um bei Bedarf zuBlueFragment
zu wechseln, und setzen Sie dann den Wert vongotoBlueFragment
zurück, um anzugeben, dass der Wechsel abgeschlossen ist. - Achten Sie darauf, dass in Ihrem Code die Variable
gotoBlueFragment
auf den Wert gesetzt wird, der die Navigation auslöst, wenn die App vonRedFragment
zuBlueFragment
wechseln muss. - In Ihrem Code muss ein
onClick
-Handler für dasView
definiert sein, auf das der Nutzer klickt, um zuBlueFragment
zu gelangen. Dort beobachtet deronClick
-Handler dengoToBlueFragment
-Wert.
Frage 2
Mit LiveData
können Sie festlegen, ob ein Button
aktiviert (anklickbar) ist oder nicht. Wie würden Sie dafür sorgen, dass Ihre App die UpdateNumber
-Schaltfläche so ändert, dass:
- Die Schaltfläche ist aktiviert, wenn
myNumber
einen Wert größer als 5 hat. - Die Schaltfläche ist nicht aktiviert, wenn
myNumber
gleich oder kleiner als 5 ist.
Angenommen, das Layout, das die Schaltfläche UpdateNumber
enthält, enthält die Variable <data>
für NumbersViewModel
, wie hier gezeigt:
<data> <variable name="NumbersViewModel" type="com.example.android.numbersapp.NumbersViewModel" /> </data>
Angenommen, die ID der Schaltfläche in der Layoutdatei ist:
android:id="@+id/update_number_button"
Was müssen Sie noch tun? Wähle alle zutreffenden Antworten aus.
- Definieren Sie in der Klasse
NumbersViewModel
eineLiveData
-Variable,myNumber
, die die Zahl darstellt. Definieren Sie außerdem eine Variable, deren Wert durch Aufrufen vonTransform.map()
für die VariablemyNumber
festgelegt wird. Dadurch wird ein boolescher Wert zurückgegeben, der angibt, ob die Zahl größer als 5 ist.
Fügen Sie in derViewModel
den folgenden Code hinzu:
val myNumber: LiveData<Int>
val enableUpdateNumberButton = Transformations.map(myNumber) {
myNumber > 5
}
- Legen Sie im XML-Layout das Attribut
android:enabled
desupdate_number_button button
-Elements aufNumberViewModel.enableUpdateNumbersButton
fest.
android:enabled="@{NumbersViewModel.enableUpdateNumberButton}"
- Fügen Sie im
Fragment
, in dem die KlasseNumbersViewModel
verwendet wird, einen Observer für das Attributenabled
der Schaltfläche hinzu.
Fügen Sie in derFragment
den folgenden Code hinzu:
// Observer for the enabled attribute
viewModel.enabled.observe(this, Observer<Boolean> { isEnabled ->
myNumber > 5
})
- Legen Sie in der Layoutdatei das Attribut
android:enabled
desupdate_number_button button
auf"Observable"
fest.
Links zu anderen Codelabs in diesem Kurs finden Sie auf der Landingpage für Android Kotlin Fundamentals-Codelabs.