Ten moduł Codelab jest częścią kursu Android Kotlin Fundamentals. Najwięcej korzyści przyniesie Ci ukończenie wszystkich ćwiczeń w kolejności. Wszystkie ćwiczenia z tego kursu znajdziesz na stronie docelowej kursu Android Kotlin Fundamentals.
Wprowadzenie
W tym ćwiczeniu w Codelabs przypomnimy sobie, jak używać ViewModel
i fragmentów do implementowania nawigacji. Pamiętaj, że celem jest umieszczenie logiki when w ViewModel
, ale ścieżki należy zdefiniować we fragmentach i w pliku nawigacyjnym. Aby to osiągnąć, używasz modeli widoku, fragmentów, LiveData
i obserwatorów.
Na koniec tego samouczka pokazujemy sprytny sposób śledzenia stanów przycisków przy użyciu minimalnej ilości kodu, dzięki czemu każdy przycisk jest włączony i można go kliknąć tylko wtedy, gdy ma to sens dla użytkownika.
Co warto wiedzieć
Musisz znać:
- Tworzenie podstawowego interfejsu użytkownika za pomocą aktywności, fragmentów i widoków.
- Przechodzenie między fragmentami i używanie
safeArgs
do przekazywania danych między nimi. - Wyświetlanie modeli, fabryk modeli, przekształceń i
LiveData
oraz ich obserwatorów. - Jak utworzyć bazę danych
Room
, obiekt dostępu do danych (DAO) i zdefiniować encje. - Jak używać korutyn do interakcji z bazą danych i innych długotrwałych zadań.
Czego się nauczysz
- Jak zaktualizować w bazie danych istniejący zapis jakości snu.
- Jak używać
LiveData
do śledzenia stanów przycisków. - Jak wyświetlić pasek z informacją w odpowiedzi na zdarzenie.
Jakie zadania wykonasz
- Rozszerz aplikację TrackMySleepQuality, aby zbierać ocenę jakości, dodawać ją do bazy danych i wyświetlać wynik.
- Użyj
LiveData
, aby wyświetlić pasek powiadomień. - Aby włączyć i wyłączyć przyciski, użyj
LiveData
.
W tym ćwiczeniu utworzysz funkcję rejestrowania jakości snu i ukończysz interfejs aplikacji TrackMySleepQuality.
Aplikacja ma 2 ekrany reprezentowane przez fragmenty, jak pokazano na ilustracji poniżej.
Na pierwszym ekranie (po lewej) znajdują się przyciski rozpoczynania i zatrzymywania śledzenia. Na ekranie wyświetlają się wszystkie dane snu użytkownika. Przycisk Wyczyść trwale usuwa wszystkie dane zebrane przez aplikację na temat użytkownika.
Drugi ekran, widoczny po prawej stronie, służy do wybierania oceny jakości snu. W aplikacji ocena jest przedstawiana w formie liczbowej. Na potrzeby programowania aplikacja wyświetla zarówno ikony twarzy, jak i ich odpowiedniki liczbowe.
Proces wygląda następująco:
- Użytkownik otwiera aplikację i widzi ekran śledzenia snu.
- Użytkownik klika przycisk Rozpocznij. Zapisuje to czas rozpoczęcia i wyświetla go. Przycisk Start jest wyłączony, a przycisk Stop jest włączony.
- Użytkownik klika przycisk Zatrzymaj. Zapisze to czas zakończenia i otworzy ekran jakości snu.
- Użytkownik wybiera ikonę jakości snu. Ekran zamyka się, a na ekranie śledzenia wyświetla się godzina zakończenia snu i jego jakość. Przycisk Stop jest wyłączony, a przycisk Start jest włączony. Aplikacja jest gotowa na kolejną noc.
- Przycisk Wyczyść jest włączony, gdy w bazie danych znajdują się dane. Gdy użytkownik kliknie przycisk Wyczyść, wszystkie jego dane zostaną bezpowrotnie usunięte – nie pojawi się komunikat „Czy na pewno?”.
Ta aplikacja korzysta z uproszczonej architektury, jak pokazano poniżej w kontekście pełnej architektury. Aplikacja korzysta tylko z tych komponentów:
- kontroler interfejsu,
- Wyświetl model i
LiveData
- baza danych Room,
W tym ćwiczeniu w Codelabs zakładamy, że wiesz, jak implementować nawigację za pomocą fragmentów i pliku nawigacji. Aby ułatwić Ci pracę, udostępniamy sporą część tego kodu.
Krok 1. Sprawdź kod
- Aby rozpocząć, użyj własnego kodu z końca ostatniego ćwiczenia lub pobierz kod startowy.
- W kodzie początkowym sprawdź
SleepQualityFragment
. Ta klasa rozszerza układ, pobiera aplikację i zwracabinding.root
. - Otwórz plik navigation.xml w edytorze projektu. Widzisz, że istnieje ścieżka nawigacji z
SleepTrackerFragment
doSleepQualityFragment
i zSleepQualityFragment
doSleepTrackerFragment
. - Sprawdź kod pod kątem navigation.xml. W szczególności poszukaj
<argument>
o nazwiesleepNightKey
.
Gdy użytkownik przechodzi zSleepTrackerFragment
doSleepQualityFragment,
, aplikacja przekazujesleepNightKey
doSleepQualityFragment
w przypadku nocy, która wymaga aktualizacji.
Krok 2. Dodaj nawigację do śledzenia jakości snu
W grafie nawigacji są już ścieżki z SleepTrackerFragment
do SleepQualityFragment
i z powrotem. Nie ma jednak jeszcze kodu obsługi kliknięć, który implementuje nawigację z jednego fragmentu do drugiego. Dodaj ten kod w ViewModel
.
W funkcji obsługi kliknięć ustawiasz LiveData
, który zmienia się, gdy chcesz, aby aplikacja przechodziła do innego miejsca docelowego. Fragment przestrzega tego LiveData
. Gdy dane się zmienią, fragment przejdzie do miejsca docelowego i powiadomi model widoku, że zadanie zostało wykonane, co spowoduje zresetowanie zmiennej stanu.
- Otwórz pokój
SleepTrackerViewModel
. Musisz dodać nawigację, aby po kliknięciu przez użytkownika przycisku Stop aplikacja przechodziła do ekranuSleepQualityFragment
, na którym można ocenić jakość. - W
SleepTrackerViewModel
utwórzLiveData
, który będzie się zmieniać, gdy chcesz, aby aplikacja przechodziła doSleepQualityFragment
. Użyj hermetyzacji, aby udostępnić tylko wersjęLiveData
, którą można pobrać, wViewModel
.
Ten kod możesz umieścić w dowolnym miejscu na najwyższym poziomie treści zajęć.
private val _navigateToSleepQuality = MutableLiveData<SleepNight>()
val navigateToSleepQuality: LiveData<SleepNight>
get() = _navigateToSleepQuality
- Dodaj funkcję
doneNavigating()
, która resetuje zmienną wywołującą nawigację.
fun doneNavigating() {
_navigateToSleepQuality.value = null
}
- W funkcji obsługi kliknięcia przycisku Stop
onStopTracking()
wywołaj przejście doSleepQualityFragment
. Ustaw zmienną _navigateToSleepQuality
na końcu funkcji jako ostatni element w blokulaunch{}
. Pamiętaj, że ta zmienna jest ustawiona nanight
. Gdy ta zmienna ma wartość, aplikacja przechodzi doSleepQualityFragment
, przekazując noc.
_navigateToSleepQuality.value = oldNight
SleepTrackerFragment
musi obserwować _navigateToSleepQuality
, aby aplikacja wiedziała, kiedy przejść do następnego ekranu. WSleepTrackerFragment
wonCreateView()
dodaj obserwatora dlanavigateToSleepQuality()
. Pamiętaj, że import w tym przypadku jest niejednoznaczny i musisz zaimportowaćandroidx.lifecycle.Observer
.
sleepTrackerViewModel.navigateToSleepQuality.observe(this, Observer {
})
- W bloku obserwatora przejdź do identyfikatora bieżącej nocy i przekaż go dalej, a następnie wywołaj funkcję
doneNavigating()
. Jeśli import jest niejednoznaczny, zaimportujandroidx.navigation.fragment.findNavController
.
night ->
night?.let {
this.findNavController().navigate(
SleepTrackerFragmentDirections
.actionSleepTrackerFragmentToSleepQualityFragment(night.nightId))
sleepTrackerViewModel.doneNavigating()
}
- Zbuduj i uruchom aplikację. Kliknij Start, a potem Stop. Spowoduje to przejście do ekranu
SleepQualityFragment
. Aby wrócić, użyj systemowego przycisku Wstecz.
W tym zadaniu zapiszesz jakość snu i wrócisz do fragmentu śledzenia snu. Wyświetlacz powinien automatycznie zaktualizować się, aby pokazać użytkownikowi zaktualizowaną wartość. Musisz utworzyć ViewModel
i ViewModelFactory
oraz zaktualizować SleepQualityFragment
.
Krok 1. Utwórz ViewModel i ViewModelFactory
- W pakiecie
sleepquality
utwórz lub otwórz plik SleepQualityViewModel.kt. - Utwórz klasę
SleepQualityViewModel
, która przyjmuje jako argumentysleepNightKey
i bazę danych. Podobnie jak w przypadkuSleepTrackerViewModel
, musisz przekazaćdatabase
z fabryki. Musisz też przekazaćsleepNightKey
z nawigacji.
class SleepQualityViewModel(
private val sleepNightKey: Long = 0L,
val database: SleepDatabaseDao) : ViewModel() {
}
- W klasie
SleepQualityViewModel
zdefiniujJob
iuiScope
oraz zastąponCleared()
.
private val viewModelJob = Job()
private val uiScope = CoroutineScope(Dispatchers.Main + viewModelJob)
override fun onCleared() {
super.onCleared()
viewModelJob.cancel()
}
- Aby wrócić do
SleepTrackerFragment
, używając tego samego wzorca co powyżej, zadeklaruj_navigateToSleepTracker
. Zaimplementuj funkcjenavigateToSleepTracker
idoneNavigating()
.
private val _navigateToSleepTracker = MutableLiveData<Boolean?>()
val navigateToSleepTracker: LiveData<Boolean?>
get() = _navigateToSleepTracker
fun doneNavigating() {
_navigateToSleepTracker.value = null
}
- Utwórz jeden moduł obsługi kliknięć,
onSetSleepQuality()
, do użycia we wszystkich obrazach dotyczących jakości snu.
Użyj tego samego wzorca korutyny co w poprzednim laboratorium:
- Uruchom korutynę w
uiScope
i przełącz się na dyspozytor wejścia/wyjścia. - Otrzymaj
tonight
, korzystając zsleepNightKey
. - Ustaw jakość snu.
- Zaktualizuj bazę danych.
- Wywołaj nawigację.
Zwróć uwagę, że w przykładzie kodu poniżej cała praca jest wykonywana w procedurze obsługi kliknięcia, zamiast wyodrębniać operację na bazie danych w innym kontekście.
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
}
}
- W pakiecie
sleepquality
utwórz lub otwórz plikSleepQualityViewModelFactory.kt
i dodaj klasęSleepQualityViewModelFactory
, jak pokazano poniżej. Ta klasa używa wersji tego samego kodu szablonowego, który już znasz. Sprawdź kod, zanim przejdziesz dalej.
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")
}
}
Krok 2. Zaktualizuj element SleepQualityFragment
- Otwórz pokój
SleepQualityFragment.kt
. - W
onCreateView()
po otrzymaniuapplication
musisz pobraćarguments
, który był dołączony do nawigacji. Te argumenty są wSleepQualityFragmentArgs
. Musisz je wyodrębnić z pakietu.
val arguments = SleepQualityFragmentArgs.fromBundle(arguments!!)
- Następnie zdobądź
dataSource
.
val dataSource = SleepDatabase.getInstance(application).sleepDatabaseDao
- Utwórz fabrykę, przekazując
dataSource
isleepNightKey
.
val viewModelFactory = SleepQualityViewModelFactory(arguments.sleepNightKey, dataSource)
- Uzyskaj referencję
ViewModel
.
val sleepQualityViewModel =
ViewModelProviders.of(
this, viewModelFactory).get(SleepQualityViewModel::class.java)
- Dodaj
ViewModel
do obiektu powiązania. (Jeśli zobaczysz błąd dotyczący obiektu powiązania, na razie go zignoruj).
binding.sleepQualityViewModel = sleepQualityViewModel
- Dodaj obserwatora. Gdy pojawi się prośba, zaimportuj
androidx.lifecycle.Observer
.
sleepQualityViewModel.navigateToSleepTracker.observe(this, Observer {
if (it == true) { // Observed state is true.
this.findNavController().navigate(
SleepQualityFragmentDirections.actionSleepQualityFragmentToSleepTrackerFragment())
sleepQualityViewModel.doneNavigating()
}
})
Krok 3. Zaktualizuj plik układu i uruchom aplikację
- Otwórz plik układu
fragment_sleep_quality.xml
. W bloku<data>
dodaj zmienną dlaSleepQualityViewModel
.
<data>
<variable
name="sleepQualityViewModel"
type="com.example.android.trackmysleepquality.sleepquality.SleepQualityViewModel" />
</data>
- Do każdego z 6 obrazów dotyczących jakości snu dodaj obsługę kliknięcia, taką jak poniżej. Dopasuj ocenę jakości do obrazu.
android:onClick="@{() -> sleepQualityViewModel.onSetSleepQuality(5)}"
- Wyczyść i ponownie skompiluj projekt. Powinno to rozwiązać wszelkie błędy związane z obiektem wiązania. W przeciwnym razie wyczyść pamięć podręczną (File > Invalidate Caches / Restart) i ponownie skompiluj aplikację.
Gratulacje! Właśnie udało Ci się utworzyć kompletną aplikację bazy danych Room
za pomocą korutyn.
Teraz aplikacja działa prawidłowo. Użytkownik może klikać Start i Stop dowolną liczbę razy. Gdy użytkownik kliknie Stop (Zakończ), może ocenić jakość snu. Gdy użytkownik kliknie Wyczyść, wszystkie dane zostaną wyczyszczone w tle bez powiadomienia. Wszystkie przyciski są jednak zawsze włączone i można je kliknąć, co nie powoduje awarii aplikacji, ale umożliwia użytkownikom tworzenie niepełnych nocy snu.
W tym ostatnim zadaniu dowiesz się, jak używać map przekształceń do zarządzania widocznością przycisków, aby użytkownicy mogli dokonywać tylko właściwych wyborów. Możesz użyć podobnej metody, aby wyświetlić przyjazny komunikat po wyczyszczeniu wszystkich danych.
Krok 1. Zaktualizuj stany przycisków
Chodzi o ustawienie stanu przycisku tak, aby na początku tylko przycisk Start był włączony, czyli klikalny.
Gdy użytkownik kliknie Start, przycisk Stop zostanie włączony, a przycisk Start – wyłączony. Przycisk Wyczyść jest włączony tylko wtedy, gdy w bazie danych znajdują się dane.
- Otwórz plik układu
fragment_sleep_tracker.xml
. - Dodaj właściwość
android:enabled
do każdego przycisku. Właściwośćandroid:enabled
to wartość logiczna, która wskazuje, czy przycisk jest włączony. (Przycisk aktywny można kliknąć, a nieaktywny – nie). Nadaj właściwości wartość zmiennej stanu, którą za chwilę zdefiniujesz.
start_button
:
android:enabled="@{sleepTrackerViewModel.startButtonVisible}"
stop_button
:
android:enabled="@{sleepTrackerViewModel.stopButtonVisible}"
clear_button
:
android:enabled="@{sleepTrackerViewModel.clearButtonVisible}"
- Otwórz
SleepTrackerViewModel
i utwórz 3 odpowiednie zmienne. Przypisz każdej zmiennej przekształcenie, które ją testuje.
- Przycisk Start powinien być włączony, gdy
tonight
ma wartośćnull
. - Przycisk Zatrzymaj powinien być włączony, gdy
tonight
nie jest równenull
. - Przycisk Wyczyść powinien być włączony tylko wtedy, gdy
nights
, a tym samym baza danych, zawiera dane o nocach snu.
val startButtonVisible = Transformations.map(tonight) {
it == null
}
val stopButtonVisible = Transformations.map(tonight) {
it != null
}
val clearButtonVisible = Transformations.map(nights) {
it?.isNotEmpty()
}
- Uruchom aplikację i wypróbuj przyciski.
Krok 2. Użyj paska powiadomień, aby powiadomić użytkownika
Gdy użytkownik wyczyści bazę danych, wyświetl potwierdzenie za pomocą widżetu Snackbar
. Pasek powiadomień wyświetla krótki komunikat u dołu ekranu, który informuje o wyniku działania. Snackbar znika po upływie określonego czasu, po interakcji użytkownika w innym miejscu na ekranie lub po przesunięciu go przez użytkownika poza ekran.
Wyświetlanie paska informacyjnego jest zadaniem interfejsu i powinno odbywać się we fragmencie. Decyzja o wyświetleniu paska z informacją jest podejmowana w ViewModel
. Aby skonfigurować i wywołać pasek z informacją o usunięciu danych, możesz użyć tej samej techniki co w przypadku wywoływania nawigacji.
- W sekcji
SleepTrackerViewModel
utwórz zdarzenie hermetyzowane.
private var _showSnackbarEvent = MutableLiveData<Boolean>()
val showSnackBarEvent: LiveData<Boolean>
get() = _showSnackbarEvent
- Następnie wdróż
doneShowingSnackbar()
.
fun doneShowingSnackbar() {
_showSnackbarEvent.value = false
}
- W
SleepTrackerFragment
w sekcjionCreateView()
dodaj obserwatora:
sleepTrackerViewModel.showSnackBarEvent.observe(this, Observer { })
- W bloku obserwatora wyświetl pasek powiadomień i natychmiast zresetuj zdarzenie.
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()
}
- W
SleepTrackerViewModel
wywołaj zdarzenie w metodzieonClear()
. Aby to zrobić, ustaw wartość zdarzenia natrue
w blokulaunch
:
_showSnackbarEvent.value = true
- Skompiluj i uruchom aplikację.
Projekt Android Studio: TrackMySleepQualityFinal
Wprowadzenie w tej aplikacji funkcji śledzenia jakości snu jest jak zagranie znanego utworu w nowej tonacji. Szczegóły się zmieniają, ale podstawowy wzorzec tego, co zostało zrobione w poprzednich ćwiczeniach w tej lekcji, pozostaje taki sam. Znajomość tych wzorców znacznie przyspiesza kodowanie, ponieważ możesz ponownie wykorzystywać kod z istniejących aplikacji. Oto niektóre wzorce użyte do tej pory w tym kursie:
- Utwórz
ViewModel
iViewModelFactory
oraz skonfiguruj źródło danych. - Wywołaj nawigację. Aby rozdzielić zadania, umieść moduł obsługi kliknięć w modelu widoku, a nawigację we fragmencie.
- Używaj hermetyzacji z
LiveData
, aby śledzić zmiany stanu i na nie reagować. - Używaj przekształceń z parametrem
LiveData
. - Utwórz bazę danych singleton.
- Skonfiguruj coroutines do operacji na bazie danych.
Włączanie nawigacji
Możliwe ścieżki nawigacji między fragmentami określasz w pliku nawigacji. Nawigację z jednego fragmentu do drugiego można wywołać na kilka sposobów. Obejmują one:
- Zdefiniuj moduły obsługi
onClick
, aby wywoływać nawigację do fragmentu docelowego. - Aby włączyć nawigację między fragmentami:
- Określ wartość
LiveData
, aby rejestrować, czy ma nastąpić nawigacja. - Dołącz obserwatora do tej wartości
LiveData
. - Kod zmienia tę wartość, gdy trzeba wywołać nawigację lub gdy nawigacja się zakończy.
Ustawianie atrybutu android:enabled
- Atrybut
android:enabled
jest zdefiniowany wTextView
i dziedziczony przez wszystkie podklasy, w tymButton
. - Atrybut
android:enabled
określa, czyView
jest włączony. Znaczenie słowa „włączone” różni się w zależności od podklasy. Na przykład wyłączony elementEditText
uniemożliwia użytkownikowi edytowanie zawartego w nim tekstu, a wyłączony elementButton
uniemożliwia użytkownikowi kliknięcie przycisku. - Atrybut
enabled
nie jest taki sam jak atrybutvisibility
. - Za pomocą map przekształceń możesz ustawić wartość atrybutu
enabled
przycisków na podstawie stanu innego obiektu lub zmiennej.
Inne kwestie omówione w tych ćwiczeniach z programowania:
- Aby wywołać powiadomienia dla użytkownika, możesz użyć tej samej techniki, której używasz do wywoływania nawigacji.
- Możesz użyć
Snackbar
, aby powiadomić użytkownika.
Kurs Udacity:
Dokumentacja dla deweloperów aplikacji na Androida:
W tej sekcji znajdziesz listę możliwych zadań domowych dla uczniów, którzy wykonują ten moduł w ramach kursu prowadzonego przez instruktora. Nauczyciel musi:
- W razie potrzeby przypisz pracę domową.
- Poinformuj uczniów, jak przesyłać projekty.
- Oceń zadania domowe.
Instruktorzy mogą korzystać z tych sugestii w dowolnym zakresie i mogą zadawać inne zadania domowe, które uznają za odpowiednie.
Jeśli wykonujesz ten kurs samodzielnie, możesz użyć tych zadań domowych, aby sprawdzić swoją wiedzę.
Odpowiedz na te pytania
Pytanie 1
Jednym ze sposobów umożliwienia aplikacji wywoływania nawigacji z jednego fragmentu do drugiego jest użycie wartości LiveData
, aby wskazać, czy wywołać nawigację.
Jakie kroki należy wykonać, aby użyć wartości LiveData
o nazwie gotoBlueFragment
do wywołania nawigacji z czerwonego fragmentu do niebieskiego? Zaznacz wszystkie pasujące opcje:
- W polu
ViewModel
zdefiniuj wartośćLiveData
gotoBlueFragment
. - W polu
RedFragment
sprawdź wartośćgotoBlueFragment
. Zaimplementuj kodobserve{}
, aby w odpowiednich przypadkach przejść doBlueFragment
, a następnie zresetuj wartośćgotoBlueFragment
, aby wskazać, że nawigacja została zakończona. - Upewnij się, że Twój kod ustawia zmienną
gotoBlueFragment
na wartość, która wywołuje nawigację, gdy aplikacja musi przejść zRedFragment
doBlueFragment
. - Upewnij się, że kod definiuje procedurę obsługi
onClick
dla elementuView
, który użytkownik klika, aby przejść do elementuBlueFragment
, gdzie procedura obsługionClick
obserwuje wartośćgoToBlueFragment
.
Pytanie 2
Możesz zmienić, czy Button
jest włączony (można go kliknąć), czy nie, za pomocą LiveData
. Jak możesz się upewnić, że aplikacja zmieni przycisk UpdateNumber
w taki sposób, aby:
- Przycisk jest włączony, jeśli wartość
myNumber
jest większa niż 5. - Przycisk nie jest włączony, jeśli wartość
myNumber
wynosi 5 lub mniej.
Załóżmy, że układ zawierający przycisk UpdateNumber
zawiera zmienną <data>
dla elementu NumbersViewModel
, jak pokazano tutaj:
<data> <variable name="NumbersViewModel" type="com.example.android.numbersapp.NumbersViewModel" /> </data>
Załóżmy, że identyfikator przycisku w pliku układu jest taki:
android:id="@+id/update_number_button"
Co jeszcze musisz zrobić? Zaznacz wszystkie pasujące opcje.
- W klasie
NumbersViewModel
zdefiniuj zmiennąLiveData
,myNumber
, która reprezentuje liczbę. Zdefiniuj też zmienną, której wartość jest ustawiana przez wywołanie funkcjiTransform.map()
na zmiennejmyNumber
. Zwraca ona wartość logiczną wskazującą, czy liczba jest większa od 5.
W plikuViewModel
dodaj ten kod:
val myNumber: LiveData<Int>
val enableUpdateNumberButton = Transformations.map(myNumber) {
myNumber > 5
}
- W układzie XML ustaw atrybut
android:enabled
elementuupdate_number_button button
naNumberViewModel.enableUpdateNumbersButton
.
android:enabled="@{NumbersViewModel.enableUpdateNumberButton}"
- W elemencie
Fragment
, który używa klasyNumbersViewModel
, dodaj obserwatora do atrybutuenabled
przycisku.
W plikuFragment
dodaj ten kod:
// Observer for the enabled attribute
viewModel.enabled.observe(this, Observer<Boolean> { isEnabled ->
myNumber > 5
})
- W pliku układu ustaw atrybut
android:enabled
elementuupdate_number_button button
na"Observable"
.
Przejdź do następnej lekcji:
Linki do innych ćwiczeń z tego kursu znajdziesz na stronie docelowej ćwiczeń z podstaw języka Kotlin na Androidzie.