Android Kotlin Fundamentals 06.3: Use LiveData to control button states

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 whenViewModel, 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

  1. Aby rozpocząć, użyj własnego kodu z końca ostatniego ćwiczenia lub pobierz kod startowy.
  2. W kodzie początkowym sprawdź SleepQualityFragment. Ta klasa rozszerza układ, pobiera aplikację i zwraca binding.root.
  3. Otwórz plik navigation.xml w edytorze projektu. Widzisz, że istnieje ścieżka nawigacji z SleepTrackerFragment do SleepQualityFragment i z SleepQualityFragment do SleepTrackerFragment.



  4. Sprawdź kod pod kątem navigation.xml. W szczególności poszukaj <argument> o nazwie sleepNightKey.

    Gdy użytkownik przechodzi z SleepTrackerFragment do SleepQualityFragment,, aplikacja przekazuje sleepNightKey do SleepQualityFragment 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.

  1. Otwórz pokój SleepTrackerViewModel. Musisz dodać nawigację, aby po kliknięciu przez użytkownika przycisku Stop aplikacja przechodziła do ekranu SleepQualityFragment, na którym można ocenić jakość.
  2. SleepTrackerViewModel utwórz LiveData, który będzie się zmieniać, gdy chcesz, aby aplikacja przechodziła do SleepQualityFragment. Użyj hermetyzacji, aby udostępnić tylko wersję LiveData, którą można pobrać, w ViewModel.

    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
  1. Dodaj funkcję doneNavigating(), która resetuje zmienną wywołującą nawigację.
fun doneNavigating() {
   _navigateToSleepQuality.value = null
}
  1. W funkcji obsługi kliknięcia przycisku Stop onStopTracking() wywołaj przejście do SleepQualityFragment. Ustaw zmienną _navigateToSleepQuality na końcu funkcji jako ostatni element w bloku launch{}. Pamiętaj, że ta zmienna jest ustawiona na night. Gdy ta zmienna ma wartość, aplikacja przechodzi do SleepQualityFragment, przekazując noc.
_navigateToSleepQuality.value = oldNight
  1. SleepTrackerFragment musi obserwować _navigateToSleepQuality, aby aplikacja wiedziała, kiedy przejść do następnego ekranu. W SleepTrackerFragment w onCreateView() dodaj obserwatora dla navigateToSleepQuality(). Pamiętaj, że import w tym przypadku jest niejednoznaczny i musisz zaimportować androidx.lifecycle.Observer.
sleepTrackerViewModel.navigateToSleepQuality.observe(this, Observer {
})

  1. 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, zaimportuj androidx.navigation.fragment.findNavController.
night ->
night?.let {
   this.findNavController().navigate(
           SleepTrackerFragmentDirections
                   .actionSleepTrackerFragmentToSleepQualityFragment(night.nightId))
   sleepTrackerViewModel.doneNavigating()
}
  1. 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

  1. W pakiecie sleepquality utwórz lub otwórz plik SleepQualityViewModel.kt.
  2. Utwórz klasę SleepQualityViewModel, która przyjmuje jako argumenty sleepNightKey i bazę danych. Podobnie jak w przypadku SleepTrackerViewModel, musisz przekazać database z fabryki. Musisz też przekazać sleepNightKey z nawigacji.
class SleepQualityViewModel(
       private val sleepNightKey: Long = 0L,
       val database: SleepDatabaseDao) : ViewModel() {
}
  1. W klasie SleepQualityViewModel zdefiniuj Job i uiScope oraz zastąp onCleared().
private val viewModelJob = Job()
private val uiScope = CoroutineScope(Dispatchers.Main + viewModelJob)

override fun onCleared() {
   super.onCleared()
   viewModelJob.cancel()
}
  1. Aby wrócić do SleepTrackerFragment, używając tego samego wzorca co powyżej, zadeklaruj _navigateToSleepTracker. Zaimplementuj funkcje navigateToSleepTrackerdoneNavigating().
private val _navigateToSleepTracker = MutableLiveData<Boolean?>()

val navigateToSleepTracker: LiveData<Boolean?>
   get() = _navigateToSleepTracker

fun doneNavigating() {
   _navigateToSleepTracker.value = null
}
  1. 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 z sleepNightKey.
  • 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
        }
    }
  1. W pakiecie sleepquality utwórz lub otwórz plik SleepQualityViewModelFactory.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

  1. Otwórz pokój SleepQualityFragment.kt.
  2. onCreateView() po otrzymaniu application musisz pobrać arguments, który był dołączony do nawigacji. Te argumenty są w SleepQualityFragmentArgs. Musisz je wyodrębnić z pakietu.
val arguments = SleepQualityFragmentArgs.fromBundle(arguments!!)
  1. Następnie zdobądź dataSource.
val dataSource = SleepDatabase.getInstance(application).sleepDatabaseDao
  1. Utwórz fabrykę, przekazując dataSource i sleepNightKey.
val viewModelFactory = SleepQualityViewModelFactory(arguments.sleepNightKey, dataSource)
  1. Uzyskaj referencję ViewModel.
val sleepQualityViewModel =
       ViewModelProviders.of(
               this, viewModelFactory).get(SleepQualityViewModel::class.java)
  1. Dodaj ViewModel do obiektu powiązania. (Jeśli zobaczysz błąd dotyczący obiektu powiązania, na razie go zignoruj).
binding.sleepQualityViewModel = sleepQualityViewModel
  1. 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ę

  1. Otwórz plik układu fragment_sleep_quality.xml. W bloku <data> dodaj zmienną dla SleepQualityViewModel.
 <data>
       <variable
           name="sleepQualityViewModel"
           type="com.example.android.trackmysleepquality.sleepquality.SleepQualityViewModel" />
   </data>
  1. 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)}"
  1. 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ć StartStop 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.

  1. Otwórz plik układu fragment_sleep_tracker.xml.
  2. 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}"
  1. 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ówne null.
  • 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()
}
  1. 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.

  1. W sekcji SleepTrackerViewModel utwórz zdarzenie hermetyzowane.
private var _showSnackbarEvent = MutableLiveData<Boolean>()

val showSnackBarEvent: LiveData<Boolean>
   get() = _showSnackbarEvent
  1. Następnie wdróż doneShowingSnackbar().
fun doneShowingSnackbar() {
   _showSnackbarEvent.value = false
}
  1. SleepTrackerFragment w sekcji onCreateView() dodaj obserwatora:
sleepTrackerViewModel.showSnackBarEvent.observe(this, Observer { })
  1. 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()
   }
  1. SleepTrackerViewModel wywołaj zdarzenie w metodzie onClear(). Aby to zrobić, ustaw wartość zdarzenia na true w bloku launch:
_showSnackbarEvent.value = true
  1. 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 ViewModelViewModelFactory 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 w TextView i dziedziczony przez wszystkie podklasy, w tym Button.
  • Atrybut android:enabled określa, czy View jest włączony. Znaczenie słowa „włączone” różni się w zależności od podklasy. Na przykład wyłączony element EditText uniemożliwia użytkownikowi edytowanie zawartego w nim tekstu, a wyłączony element Button uniemożliwia użytkownikowi kliknięcie przycisku.
  • Atrybut enabled nie jest taki sam jak atrybut visibility.
  • 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 kod observe{}, aby w odpowiednich przypadkach przejść do BlueFragment, 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ść z RedFragment do BlueFragment.
  • Upewnij się, że kod definiuje procedurę obsługi onClick dla elementu View, który użytkownik klika, aby przejść do elementu BlueFragment, gdzie procedura obsługi onClick 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 funkcji Transform.map() na zmiennej myNumber. Zwraca ona wartość logiczną wskazującą, czy liczba jest większa od 5.

    W pliku ViewModel dodaj ten kod:
val myNumber: LiveData<Int>

val enableUpdateNumberButton = Transformations.map(myNumber) {
   myNumber > 5
}
  • W układzie XML ustaw atrybut android:enabled elementu update_number_button button na NumberViewModel.enableUpdateNumbersButton.
android:enabled="@{NumbersViewModel.enableUpdateNumberButton}"
  • W elemencie Fragment, który używa klasy NumbersViewModel, dodaj obserwatora do atrybutu enabled przycisku.

    W pliku Fragment 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 elementu update_number_button button na "Observable".

Przejdź do następnej lekcji: 7.1. Podstawy RecyclerView

Linki do innych ćwiczeń z tego kursu znajdziesz na stronie docelowej ćwiczeń z podstaw języka Kotlin na Androidzie.