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 poprzednich ćwiczeniach z programowania zaktualizowaliśmy aplikację TrackMySleepQuality, aby wyświetlała dane o jakości snu w RecyclerView. Techniki, których używasz do tworzenia pierwszego RecyclerView, wystarczą w przypadku większości RecyclerViews wyświetlających proste listy, które nie są zbyt duże. Istnieje jednak wiele technik, które sprawiają, że RecyclerView jest bardziej wydajny w przypadku dużych list, a kod jest łatwiejszy w utrzymaniu i rozbudowie w przypadku złożonych list i siatek.
W tym ćwiczeniu z programowania rozbudujesz aplikację do śledzenia snu z poprzedniego ćwiczenia. Dowiesz się, jak skuteczniej aktualizować listę danych o śnie, i jak używać powiązania danych z RecyclerView. (Jeśli nie masz aplikacji z poprzednich zajęć, możesz pobrać kod początkowy do tych zajęć).
Co warto wiedzieć
- Tworzenie podstawowego interfejsu użytkownika za pomocą aktywności, fragmentów i widoków.
- przechodzenie między fragmentami i używanie
safeArgsdo przekazywania danych między fragmentami; - Wyświetlanie modeli, fabryk modeli, przekształceń i
LiveDataoraz ich obserwatorów. - Jak utworzyć bazę danych
Room, utworzyć DAO i zdefiniować encje. - Jak używać korutyn do obsługi baz danych i innych długotrwałych zadań.
- Jak wdrożyć podstawowy
RecyclerViewzAdapter,ViewHolderi układem elementów.
Czego się nauczysz
- Jak używać
DiffUtildo skutecznego aktualizowania listy wyświetlanej przezRecyclerView. - Jak używać wiązania danych w przypadku
RecyclerView. - Jak używać adapterów powiązań do przekształcania danych.
Jakie zadania wykonasz
- Skorzystaj z aplikacji TrackMySleepQuality z poprzedniego samouczka z tej serii.
- Zaktualizuj
SleepNightAdapter, aby skutecznie aktualizować listę za pomocąDiffUtil. - Zaimplementuj powiązanie danych dla elementu
RecyclerView, używając adapterów powiązań do przekształcania danych.
Aplikacja do śledzenia snu ma 2 ekrany reprezentowane przez fragmenty, jak pokazano na ilustracji poniżej.
|
|
Pierwszy ekran, widoczny po lewej stronie, zawiera przyciski rozpoczynania i zatrzymywania śledzenia. Na ekranie wyświetlają się niektóre dane dotyczące 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.
Ta aplikacja jest zaprojektowana tak, aby używać kontrolera interfejsu, ViewModel i LiveData oraz bazy danych Room do przechowywania danych o śnie.

Dane o śnie są wyświetlane w RecyclerView. W tym ćwiczeniu utworzysz część DiffUtil i powiązanie danych dla RecyclerView. Po ukończeniu tego laboratorium kodowania Twoja aplikacja będzie wyglądać dokładnie tak samo, ale będzie wydajniejsza, łatwiejsza do skalowania i utrzymania.
Możesz nadal używać aplikacji SleepTracker z poprzedniego laboratorium programowania lub pobrać aplikację RecyclerViewDiffUtilDataBinding-Starter z GitHub.
- W razie potrzeby pobierz aplikację RecyclerViewDiffUtilDataBinding-Starter z GitHuba i otwórz projekt w Android Studio.
- Uruchom aplikację.
- Otwórz plik
SleepNightAdapter.kt. - Sprawdź kod, aby zapoznać się ze strukturą aplikacji. Na poniższym diagramie znajdziesz podsumowanie używania
RecyclerViewze wzorcem adaptera do wyświetlania użytkownikowi danych o śnie.

- Na podstawie danych wejściowych użytkownika aplikacja tworzy listę
SleepNightobiektów. Każdy obiektSleepNightreprezentuje jedną noc snu, jego czas trwania i jakość. - Funkcja
SleepNightAdapterdostosowuje listę obiektówSleepNightdo formatu, który może być używany i wyświetlany przezRecyclerView. - Adapter
SleepNightAdaptertworzyViewHolders, które zawierają widoki, dane i metainformacje potrzebne do wyświetlania danych w widoku recyklera. RecyclerViewużywaSleepNightAdapter, aby określić liczbę elementów do wyświetlenia (getItemCount()).RecyclerViewużywaonCreateViewHolder()ionBindViewHolder(), aby uzyskać uchwyty widoku powiązane z danymi do wyświetlenia.
Metoda notifyDataSetChanged() jest nieefektywna
Aby poinformować RecyclerView, że element na liście uległ zmianie i wymaga aktualizacji, bieżący kod wywołuje notifyDataSetChanged() w SleepNightAdapter, jak pokazano poniżej.
var data = listOf<SleepNight>()
set(value) {
field = value
notifyDataSetChanged()
}Jednak notifyDataSetChanged() informuje RecyclerView, że cała lista może być nieprawidłowa. W rezultacie RecyclerView ponownie wiąże i rysuje każdy element na liście, w tym elementy, które nie są widoczne na ekranie. To dużo niepotrzebnej pracy. W przypadku dużych lub złożonych list ten proces może trwać na tyle długo, że wyświetlacz będzie migać lub zacinać się podczas przewijania listy przez użytkownika.
Aby rozwiązać ten problem, możesz dokładnie określić, co się zmieniło w RecyclerView. RecyclerView może wtedy aktualizować tylko widoki, które uległy zmianie na ekranie.
RecyclerView ma rozbudowany interfejs API do aktualizowania pojedynczego elementu. Możesz użyć notifyItemChanged(), aby poinformować RecyclerView o zmianie elementu. Podobnych funkcji możesz używać w przypadku elementów, które zostały dodane, usunięte lub przeniesione. Możesz to zrobić ręcznie, ale to zadanie nie będzie proste i może wymagać sporo kodu.
Na szczęście istnieje lepszy sposób.
DiffUtil jest wydajny i wykonuje za Ciebie całą ciężką pracę.
RecyclerView ma klasę o nazwie DiffUtil, która służy do obliczania różnic między dwiema listami. DiffUtil porównuje starą i nową listę i wykrywa różnice. Wyszukuje elementy, które zostały dodane, usunięte lub zmienione. Następnie używa algorytmu o nazwie Eugene W. algorytmu różnicowego Myersa, aby określić minimalną liczbę zmian, które należy wprowadzić na starej liście, aby uzyskać nową listę.
Gdy DiffUtil wykryje zmiany, RecyclerView może użyć tych informacji, aby zaktualizować tylko zmienione, dodane, usunięte lub przeniesione elementy, co jest znacznie wydajniejsze niż ponowne tworzenie całej listy.
W tym zadaniu uaktualnisz SleepNightAdapter, aby używać DiffUtil do optymalizacji RecyclerView pod kątem zmian w danych.
Krok 1. Wdróż SleepNightDiffCallback
Aby korzystać z funkcji klasy DiffUtil, rozszerz DiffUtil.ItemCallback.
- Otwórz pokój
SleepNightAdapter.kt. - Pod pełną definicją klasy
SleepNightAdapterutwórz nową klasę najwyższego poziomu o nazwieSleepNightDiffCallback, która rozszerza klasęDiffUtil.ItemCallback. PrzekażSleepNightjako parametr ogólny.
class SleepNightDiffCallback : DiffUtil.ItemCallback<SleepNight>() {
}- Umieść kursor w nazwie zajęć
SleepNightDiffCallback. - Naciśnij
Alt+Enter(Option+Enterna Macu) i kliknij Implement Members (Wdróż członków). - W wyświetlonym oknie kliknij z przytrzymanym klawiszem Shift, aby wybrać metody
areItemsTheSame()iareContentsTheSame(), a potem kliknij OK.
W sekcjiSleepNightDiffCallbackzostaną wygenerowane szablony tych 2 metod, jak pokazano poniżej.DiffUtilkorzysta z tych 2 metod, aby określić, jak zmieniła się lista i jej elementy.
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.
}- W sekcji
areItemsTheSame()zastąpTODOkodem, który sprawdza, czy 2 przekazane elementySleepNight,oldIteminewItem, są takie same. Jeśli produkty mają ten sam atrybutnightId, są tym samym produktem, więc zwróć wartośćtrue. W przeciwnym razie zwróć wartośćfalse.DiffUtilużywa tego testu, aby sprawdzić, czy element został dodany, usunięty lub przeniesiony.
override fun areItemsTheSame(oldItem: SleepNight, newItem: SleepNight): Boolean {
return oldItem.nightId == newItem.nightId
}- W
areContentsTheSame()sprawdź, czyoldIteminewItemzawierają te same dane, czyli czy są równe. Sprawdzanie równości obejmie wszystkie pola, ponieważSleepNightto klasa danych. KlasyDataautomatycznie definiująequalsi kilka innych metod. Jeśli występują różnice międzyoldItemanewItem, ten kod informujeDiffUtil, że element został zaktualizowany.
override fun areContentsTheSame(oldItem: SleepNight, newItem: SleepNight): Boolean {
return oldItem == newItem
}Wyświetlanie zmieniającej się listy za pomocą elementu RecyclerView to powszechny wzorzec. RecyclerView udostępnia klasę adaptera ListAdapter, która pomaga tworzyć adapter RecyclerView oparty na liście.
ListAdapter śledzi listę i powiadamia adapter o jej aktualizacji.
Krok 1. Zmień adapter, aby rozszerzyć ListAdapter
- W pliku
SleepNightAdapter.ktzmień sygnaturę klasySleepNightAdapter, aby rozszerzyćListAdapter. - Jeśli pojawi się prośba, zaimportuj
androidx.recyclerview.widget.ListAdapter. - Dodaj
SleepNightjako pierwszy argument do funkcjiListAdapterprzedSleepNightAdapter.ViewHolder. - Dodaj
SleepNightDiffCallback()jako parametr konstruktora.ListAdapterwykorzysta tę informację, aby określić, co się zmieniło na liście. Gotowy podpis klasySleepNightAdapterpowinien wyglądać jak poniżej.
class SleepNightAdapter : ListAdapter<SleepNight, SleepNightAdapter.ViewHolder>(SleepNightDiffCallback()) {- W klasie
SleepNightAdapterusuń poledata, w tym setter. Nie jest już potrzebna, ponieważListAdapterśledzi listę za Ciebie. - Usuń zastąpienie
getItemCount(), ponieważListAdapterimplementuje tę metodę za Ciebie. - Aby usunąć błąd w
onBindViewHolder(), zmień zmiennąitem. Zamiast używaćdatado uzyskiwaniaitem, wywołuj metodęgetItem(position)udostępnianą przezListAdapter.
val item = getItem(position)Krok 2. Użyj funkcji submitList(), aby aktualizować listę
Kod musi informować ListAdapter o dostępności zmienionej listy. ListAdapter udostępnia metodę o nazwie submitList(), która informuje ListAdapter o dostępności nowej wersji listy. Gdy ta metoda jest wywoływana, ListAdapter porównuje nową listę ze starą i wykrywa elementy, które zostały dodane, usunięte, przeniesione lub zmienione. Następnie ListAdapter aktualizuje wyświetlane przez RecyclerView produkty.
- Otwórz pokój
SleepTrackerFragment.kt. - W
onCreateView()w obserwatorze nasleepTrackerViewModelznajdź błąd, w którym występuje odwołanie do usuniętej zmiennejdata. - Zastąp
adapter.data = itpołączeniem z numeremadapter.submitList(it). Zaktualizowany kod znajdziesz poniżej.
sleepTrackerViewModel.nights.observe(viewLifecycleOwner, Observer {
it?.let {
adapter.submitList(it)
}
})- Uruchom aplikację. Będzie działać szybciej, choć może to być niezauważalne, jeśli lista jest krótka.
W tym zadaniu użyjesz tej samej techniki co w poprzednich modułach, aby skonfigurować powiązanie danych, i wyeliminujesz wywołania funkcji findViewById().
Krok 1. Dodaj powiązanie danych do pliku układu
- Otwórz plik układu
list_item_sleep_night.xmlna karcie Tekst. - Umieść kursor na tagu
ConstraintLayouti naciśnijAlt+Enter(Option+Enterna Macu). Otworzy się menu intencji (menu „szybka poprawka”). - Wybierz Convert to data binding layout (Przekonwertuj na układ powiązania danych). Spowoduje to umieszczenie układu w tagu
<layout>i dodanie w nim tagu<data>. - W razie potrzeby przewiń z powrotem na górę i w tagu
<data>zadeklaruj zmienną o nazwiesleep. - Ustaw
typejako pełną nazwęSleepNight,com.example.android.trackmysleepquality.database.SleepNight. Gotowy tag<data>powinien wyglądać jak poniżej.
<data>
<variable
name="sleep"
type="com.example.android.trackmysleepquality.database.SleepNight"/>
</data>- Aby wymusić utworzenie obiektu
Binding, wybierz Build > Clean Project (Skompiluj > Wyczyść projekt), a potem Build > Rebuild Project (Skompiluj > Skompiluj projekt ponownie). (Jeśli problem nadal występuje, wybierz File > Invalidate Caches / Restart). Obiekt wiązaniaListItemSleepNightBindingwraz z powiązanym kodem zostanie dodany do wygenerowanych plików projektu.
Krok 2. Rozwiń układ elementu za pomocą powiązania danych
- Otwórz pokój
SleepNightAdapter.kt. - W klasie
ViewHolderznajdź metodęfrom(). - Usuń deklarację zmiennej
view.
Kod do usunięcia:
val view = layoutInflater
.inflate(R.layout.list_item_sleep_night, parent, false)- W miejscu zmiennej
viewzdefiniuj nową zmienną o nazwiebinding, która rozszerza obiekt powiązaniaListItemSleepNightBinding, jak pokazano poniżej. Zaimportuj niezbędny obiekt powiązania.
val binding =
ListItemSleepNightBinding.inflate(layoutInflater, parent, false)- Na końcu funkcji zamiast zwracać
view, zwróćbinding.
return ViewHolder(binding)- Aby pozbyć się błędu, umieść kursor na słowie
binding. NaciśnijAlt+Enter(Option+Enterna Macu), aby otworzyć menu intencji.
- Wybierz Change parameter 'itemView' type of primary constructor of class 'ViewHolder' to 'ListItemSleepNightBinding' (Zmień typ parametru „itemView” głównego konstruktora klasy „ViewHolder” na „ListItemSleepNightBinding”). Spowoduje to zaktualizowanie typu parametru klasy
ViewHolder.

- Przewiń w górę do definicji klasy
ViewHolder, aby zobaczyć zmianę w sygnaturze. Wyświetli się błąd dotyczącyitemView, ponieważ w metodziefrom()zmienionoitemViewnabinding.
W definicji klasyViewHolderkliknij prawym przyciskiem myszy jedno z wystąpieńitemViewi wybierz Refaktoryzacja > Zmień nazwę. Zmień nazwę nabinding. - Dodaj przed parametrem konstruktora
bindingznakval, aby przekształcić go we właściwość. - W wywołaniu klasy nadrzędnej
RecyclerView.ViewHolderzmień parametr zbindingnabinding.root. Musisz przekazaćView, abinding.rootto główny elementConstraintLayoutw układzie produktu. - Gotowa deklaracja klasy powinna wyglądać tak, jak pokazano poniżej.
class ViewHolder private constructor(val binding: ListItemSleepNightBinding) : RecyclerView.ViewHolder(binding.root){Widzisz też błąd dotyczący wywołań funkcji findViewById(), który musisz naprawić.
Krok 3. Zastąp findViewById()
Możesz teraz zaktualizować właściwości sleepLength, quality i qualityImage, aby używać obiektu binding zamiast findViewById().
- Zmień inicjalizacje zmiennych
sleepLength,qualityStringiqualityImage, aby używać widoków obiektubinding, jak pokazano poniżej. Po tym kod nie powinien już zawierać żadnych błędów.
val sleepLength: TextView = binding.sleepLength
val quality: TextView = binding.qualityString
val qualityImage: ImageView = binding.qualityImageGdy obiekt wiązania jest już na miejscu, nie musisz już w ogóle definiować właściwości sleepLength, quality ani qualityImage. DataBinding będzie buforować wyszukiwania, więc nie musisz deklarować tych właściwości.
- Kliknij prawym przyciskiem myszy nazwy usług
sleepLength,qualityiqualityImage. Wybierz Refactor > Inline lub naciśnijControl+Command+N(Option+Command+Nna Macu).
- Uruchom aplikację. (Jeśli projekt zawiera błędy, może być konieczne wyczyszczenie i ponowne skompilowanie projektu).
W tym zadaniu zaktualizujesz aplikację, aby używała powiązania danych z adapterami powiązań do ustawiania danych w widokach.
W poprzednich ćwiczeniach z programowania używaliśmy klasy Transformations do pobierania LiveData i generowania sformatowanych ciągów znaków do wyświetlania w widokach tekstowych. Jeśli jednak musisz powiązać różne typy lub typy złożone, możesz podać adaptery powiązań, aby ułatwić powiązanie danych z tymi typami. Adaptery powiązań to adaptery, które pobierają dane i przekształcają je w coś, co może być użyte przez powiązanie danych do powiązania widoku, np. tekstu lub obrazu.
Zaimplementujesz 3 adaptery powiązań: jeden dla obrazu wysokiej jakości i po jednym dla każdego pola tekstowego. Podsumowując, aby zadeklarować adapter powiązania, zdefiniuj metodę, która przyjmuje element i widok, i dodaj do niej adnotację @BindingAdapter. W treści metody implementujesz przekształcenie. W Kotlinie możesz napisać adapter powiązania jako funkcję rozszerzenia w klasie widoku, która otrzymuje dane.
Krok 1. Utwórz adaptery powiązań
Pamiętaj, że w tym kroku musisz zaimportować kilka zajęć, które nie będą wymienione osobno.
- Otwórz pokój
SleepNightAdapater.kt. - W klasie
ViewHolderznajdź metodębind()i przypomnij sobie, do czego służy. Kod obliczający wartościbinding.sleepLength,binding.qualityibinding.qualityImageumieścisz w adapterze. (Na razie pozostaw kod bez zmian. Przeniesiesz go w późniejszym kroku). - W pakiecie
sleeptrackerutwórz i otwórz plik o nazwieBindingUtils.kt. - Zadeklaruj funkcję rozszerzenia w
TextViewo nazwiesetSleepDurationFormattedi przekażSleepNight. Ta funkcja będzie adapterem do obliczania i formatowania czasu trwania snu.
fun TextView.setSleepDurationFormatted(item: SleepNight) {}- W treści
setSleepDurationFormattedpowiąż dane z widokiem tak jak wViewHolder.bind(). WywołajconvertDurationToFormatted(), a następnie ustawtextelementuTextViewna sformatowany tekst. (Ponieważ jest to funkcja rozszerzenia wTextView, możesz bezpośrednio uzyskać dostęp do właściwościtext).
text = convertDurationToFormatted(item.startTimeMilli, item.endTimeMilli, context.resources)- Aby poinformować o tym adapterze wiązania, dodaj do funkcji adnotację
@BindingAdapter. - Ta funkcja jest adapterem atrybutu
sleepDurationFormatted, więc przekażsleepDurationFormattedjako argument do@BindingAdapter.
@BindingAdapter("sleepDurationFormatted")- Drugi adapter ustawia jakość snu na podstawie wartości w obiekcie
SleepNight. Utwórz funkcję rozszerzenia o nazwiesetSleepQualityString()wTextViewi przekażSleepNight. - W treści powiąż dane z widokiem tak jak w
ViewHolder.bind(). WywołajconvertNumericQualityToStringi ustawtext. - Dodaj do funkcji adnotację
@BindingAdapter("sleepQualityString").
@BindingAdapter("sleepQualityString")
fun TextView.setSleepQualityString(item: SleepNight) {
text = convertNumericQualityToString(item.sleepQuality, context.resources)
}- Trzeci adapter powiązania ustawia obraz w widoku obrazu. Utwórz funkcję rozszerzenia w
ImageView, wywołajsetSleepImagei użyj kodu zViewHolder.bind(), jak pokazano poniżej.
@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
})
}Krok 2. Zaktualizuj SleepNightAdapter
- Otwórz pokój
SleepNightAdapter.kt. - Usuń wszystko w metodzie
bind(), ponieważ możesz teraz używać powiązania danych i nowych adapterów, aby wykonać tę pracę za Ciebie.
fun bind(item: SleepNight) {
}- W obiekcie
bind()przypisz stan uśpienia doitem, ponieważ musisz poinformować obiekt powiązania o nowym obiekcieSleepNight.
binding.sleep = item- Pod tym wierszem dodaj
binding.executePendingBindings(). To wywołanie jest optymalizacją, która powoduje natychmiastowe wykonanie wszystkich oczekujących wiązań danych. Zawsze warto wywoływać metodęexecutePendingBindings(), gdy używasz adapterów wiążących wRecyclerView, ponieważ może to nieco przyspieszyć określanie rozmiaru widoków.
binding.executePendingBindings()Krok 3. Dodaj powiązania do układu XML
- Otwórz pokój
list_item_sleep_night.xml. - W
ImageViewdodaj właściwośćappo takiej samej nazwie jak adapter powiązania, który ustawia obraz. Przekaż zmiennąsleep, jak pokazano poniżej.
Ta właściwość tworzy połączenie między widokiem a obiektem wiązania za pomocą adaptera. Gdy pojawi się odwołanie dosleepImage, adapter dostosuje dane zSleepNight.
app:sleepImage="@{sleep}"- Zrób to samo w przypadku widoków tekstu
sleep_lengthiquality_string. Gdy odwołujesz się dosleepDurationFormattedlubsleepQualityString, adaptery dostosowują dane zSleepNight.
app:sleepDurationFormatted="@{sleep}"app:sleepQualityString="@{sleep}"- Uruchom aplikację. Działa ona dokładnie tak samo jak wcześniej. Adaptery powiązań wykonują całą pracę związaną z formatowaniem i aktualizowaniem widoków w miarę zmian danych, co upraszcza
ViewHolderi poprawia strukturę kodu.
W przypadku kilku ostatnich ćwiczeń wyświetliłeś(-aś) tę samą listę. Zostało to zaprojektowane tak, aby pokazać, że interfejs Adapter umożliwia tworzenie kodu na wiele różnych sposobów. Im bardziej złożony jest kod, tym ważniejsze jest jego prawidłowe zaprojektowanie. W aplikacjach produkcyjnych te i inne wzorce są używane w środowisku RecyclerView. Wszystkie te wzorce działają i każdy z nich ma swoje zalety. Wybór zależy od tego, co tworzysz.
Gratulacje! Jesteś na dobrej drodze do opanowania RecyclerView na Androidzie.
Projekt Android Studio: RecyclerViewDiffUtilDataBinding.
DiffUtil:
RecyclerViewma klasę o nazwieDiffUtil, która służy do obliczania różnic między dwiema listami.DiffUtilma klasę o nazwieItemCallBack, którą rozszerzasz, aby obliczyć różnicę między dwiema listami.- W klasie
ItemCallbackmusisz zastąpić metodyareItemsTheSame()iareContentsTheSame().
ListAdapter:
- Aby bezpłatnie zarządzać listami, możesz użyć klasy
ListAdapterzamiastRecyclerView.Adapter. Jeśli jednak używaszListAdapter, musisz napisać własny adapter dla innych układów, dlatego w tym laboratorium kodu pokazujemy, jak to zrobić. - Aby otworzyć menu intencji w Android Studio, umieść kursor na dowolnym elemencie kodu i naciśnij
Alt+Enter(Option+Enterna Macu). To menu jest szczególnie przydatne do refaktoryzacji kodu i tworzenia stubów do implementacji metod. Menu jest kontekstowe, więc aby uzyskać odpowiednie menu, musisz umieścić kursor w odpowiednim miejscu.
Wiązanie danych:
- Użyj powiązania danych w układzie elementu, aby powiązać dane z widokami.
Adaptery do wiązania:
- Wcześniej używasz funkcji
Transformationsdo tworzenia ciągów znaków na podstawie danych. Jeśli musisz powiązać dane różnych lub złożonych typów, udostępnij adaptery powiązań, aby ułatwić powiązanie danych. - Aby zadeklarować adapter powiązania, zdefiniuj metodę, która przyjmuje element i widok, i dodaj do niej adnotację
@BindingAdapter. W Kotlinie możesz napisać adapter powiązania jako funkcję rozszerzenia wView. Przekaż nazwę usługi, do której dostosowuje się adapter. Na przykład:
@BindingAdapter("sleepDurationFormatted")- W układzie XML ustaw właściwość
appo takiej samej nazwie jak adapter powiązania. Przekaż zmienną z danymi. Na przykład:
.app:sleepDurationFormatted="@{sleep}"Kursy Udacity:
Dokumentacja dla deweloperów aplikacji na Androida:
- Tworzenie listy za pomocą elementu RecyclerView
RecyclerViewDiffUtil- Biblioteka powiązań danych
- Adaptery wiązań
notifyDataSetChanged()Transformations
Inne zasoby:
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
Które z tych elementów są niezbędne do korzystania z DiffUtil? Zaznacz wszystkie pasujące opcje.
▢ Wydłuż zajęcia ItemCallBack.
▢ Zastąp areItemsTheSame().
▢ Zastąp areContentsTheSame().
▢ Używaj wiązania danych, aby śledzić różnice między elementami.
Pytanie 2
Które z tych stwierdzeń dotyczących adapterów powiązań są prawdziwe?
▢ Adapter powiązania to funkcja oznaczona adnotacją @BindingAdapter.
▢ Użycie adaptera powiązań umożliwia oddzielenie formatowania danych od obiektu widoku.
▢ Jeśli chcesz używać adapterów wiążących, musisz użyć RecyclerViewAdapter.
▢ Adaptery powiązań to dobre rozwiązanie, gdy musisz przekształcić złożone dane.
Pytanie 3
Kiedy warto użyć Transformations zamiast adaptera powiązania? Zaznacz wszystkie pasujące opcje.
▢ Dane są proste.
▢ Formatujesz ciąg znaków.
▢ Twoja lista jest bardzo długa.
▢ Twój ViewHolder zawiera tylko jeden widok.
Rozpocznij kolejną lekcję:

