Te ćwiczenia są częścią kursu Android Kotlin Fundamentals. Skorzystaj z tego kursu, jeśli będziesz wykonywać kolejno kilka ćwiczeń z programowania. Wszystkie ćwiczenia z kursu są wymienione na stronie docelowej ćwiczeń z programowania na temat Kotlin.
Wprowadzenie
W ramach poprzedniego ćwiczenia z programem zaktualizowaliśmy funkcję TrackMySleepQuality, aby wyświetlać w RecyclerView
dane o jakości snu. Metody, których się nauczyłeś, gdy tworzysz pierwsze RecyclerView
, są wystarczające do większości elementów RecyclerViews
, które wyświetlają proste listy, które nie są za duże. Istnieje jednak kilka technik, które sprawiają, że RecyclerView
jest bardziej skuteczny w przypadku dużych list i ułatwia obsługę oraz rozbudowę złożonych list i siatki.
W tym ćwiczeniu wykorzystasz aplikację do monitorowania snu z poprzedniego ćwiczenia. Poznaj skuteczniejszy sposób aktualizowania listy danych dotyczących snu i naucz się korzystać z wiązań danych z RecyclerView
. (Jeśli nie masz aplikacji z poprzedniego ćwiczenia z programowania, możesz pobrać kod startowy tego ćwiczenia).
Co musisz wiedzieć
- Tworzenie podstawowego interfejsu użytkownika za pomocą aktywności, fragmentów i widoków danych.
- Przechodzenie między fragmentami i przekazywanie danych między nimi za pomocą
safeArgs
. - Wyświetlanie modeli, wyświetlanie fabryk modeli, przekształceń oraz
LiveData
i ich obserwatorów. - Jak utworzyć bazę danych
Room
, utworzyć DAO i określić encje. - Jak używać algorytmów baz danych i innych długotrwałych zadań.
- Jak wdrożyć podstawowy element
RecyclerView
z elementemAdapter
,ViewHolder
i układem elementu.
Czego się nauczysz
- Jak używać
DiffUtil
, by efektywnie aktualizować listę wyświetlaną przezRecyclerView
. - Jak używać wiązania danych z
RecyclerView
. - Jak używać adapterów wiązań do przekształcania danych.
Jakie zadania wykonasz:
- Skorzystaj z aplikacji TrackMySleepQuality z poprzedniego ćwiczenia z tej serii.
- Zaktualizuj
SleepNightAdapter
, aby skutecznie aktualizować listę za pomocą metodyDiffUtil
. - Zaimplementuj wiązanie danych w jednostce organizacyjnej
RecyclerView
, używając odpowiedniego adaptera, by przekształcić dane.
Aplikacja monitorowania snu ma 2 ekrany reprezentowane przez fragmenty, jak widać na rysunku poniżej.
Na pierwszym ekranie po lewej stronie znajdują się przyciski rozpoczynające i zatrzymujące śledzenie. Na ekranie pojawią się niektóre dane dotyczące snu użytkownika. Kliknięcie przycisku Wyczyść powoduje trwałe usunięcie wszystkich danych użytkownika zbieranych przez aplikację. Na drugim ekranie (po prawej) możesz wybrać ocenę jakości snu.
Ta aplikacja jest przeznaczona do użycia kontrolera interfejsu użytkownika ViewModel
i LiveData
oraz bazy danych Room
do przechowywania danych o śnie.
Dane dotyczące snu są wyświetlane w RecyclerView
. W tym ćwiczeniu z programowania tworzysz element DiffUtil
i wiążące dane dla interfejsu RecyclerView
. Po ukończeniu tych ćwiczeń Twoja aplikacja będzie wyglądać dokładnie tak samo, ale będzie skuteczniejsza i łatwiejsza w skalowaniu i utrzymaniu.
Możesz dalej korzystać z aplikacji SleepTracker z poprzedniego ćwiczenia z programowania. Możesz też pobrać aplikację RecyclerViewDiffUtilDataBinding-Starter z GitHuba.
- W razie potrzeby pobierz aplikację RecyclerViewDiffUtilDataBinding-Starter z GitHuba i otwórz projekt w Android Studio.
- Uruchom aplikację.
- Otwórz plik
SleepNightAdapter.kt
. - Przeanalizuj kod, aby zapoznać się ze strukturą aplikacji. W tabeli poniżej znajdziesz podsumowanie informacji o tym, jak używać
RecyclerView
z wzorcem adaptera do wyświetlania użytkownikowi danych o śnie.
- Na podstawie danych wejściowych użytkownika aplikacja tworzy listę obiektów
SleepNight
. Każdy obiektSleepNight
reprezentuje 1 noc snu, czas jego trwania oraz jakość. SleepNightAdapter
przekształca listę obiektówSleepNight
w coś, coRecyclerView
może wyświetlać i wyświetlać.- Adapter
SleepNightAdapter
tworzy kartęViewHolders
zawierającą widoki danych, dane i metadane, które zostaną wyświetlone w widoku recyklingu. RecyclerView
używaSleepNightAdapter
do określenia liczby elementów do wyświetlenia (getItemCount()
).RecyclerView
używa elementówonCreateViewHolder()
ionBindViewHolder()
, by wskazać właścicieli widoku danych powiązanych z danymi o wyświetlaniu.
Metoda powiadomieniaDataDataChanged() jest nieskuteczna
Aby poinformować zespół RecyclerView
, że element na liście został zmieniony i wymaga aktualizacji, bieżący kod wywołuje polecenie notifyDataSetChanged()
w elemencie SleepNightAdapter
, jak pokazano poniżej.
var data = listOf<SleepNight>()
set(value) {
field = value
notifyDataSetChanged()
}
notifyDataSetChanged()
informuje jednak zespół RecyclerView
, że cała lista jest potencjalnie nieprawidłowa. W rezultacie RecyclerView
ponownie łączy i ponownie usuwa każdy element na liście, w tym elementy niewidoczne na ekranie. To dużo niepotrzebna praca. W przypadku dużych i złożonych list ten proces może trwać wystarczająco długo, aby ekran migał lub przeskakiwał podczas przewijania.
Aby rozwiązać ten problem, możesz poinformować aplikację RecyclerView
dokładnie, co się zmieniło. RecyclerView
może wtedy zaktualizować tylko widoki danych wyświetlane na ekranie.
RecyclerView
ma zaawansowany interfejs API do aktualizowania jednego elementu. Możesz użyć notifyItemChanged()
, aby poinformować użytkownika RecyclerView
, że element został zmieniony. Możesz też użyć podobnych funkcji w przypadku dodanych, usuniętych lub przeniesionych elementów. Można to zrobić ręcznie, ale to zadanie nie będzie proste i może wymagać dużej ilości kodu.
Na szczęście jest lepszy sposób.
DiffUtil jest wydajna i wykonuje za Ciebie ciężką pracę
RecyclerView
ma klasę DiffUtil
, która służy do obliczania różnic między 2 listami. DiffUtil
stosuje starą i nową listę, aby pokazać, co się zmieniło. Wyszukuje elementy, które zostały dodane, usunięte lub zmienione. Następnie wykorzystuje algorytm Eugene W. (algorytm Myers's).
Gdy DiffUtil
wykryje, co się zmieniło, RecyclerView
może wykorzystać te informacje, by zaktualizować tylko te elementy, które zostały zmienione, dodane, usunięte lub przeniesione, co jest dużo bardziej efektywne niż ponawianie całej listy.
W tym zadaniu uaktualnisz SleepNightAdapter
, aby używać DiffUtil
do optymalizowania RecyclerView
pod kątem zmian w danych.
Krok 1. Zaimplementuj wywołanie zwrotne SleepNightDiffCallback
Aby móc korzystać z funkcji klasy DiffUtil
, rozszerz właściwość DiffUtil.ItemCallback
.
- Otwórz aplikację
SleepNightAdapter.kt
. - Pod pełną definicją klasy
SleepNightAdapter
utwórz nową klasę najwyższego poziomu o nazwieSleepNightDiffCallback
, która przedłużaDiffUtil.ItemCallback
. PrzekażSleepNight
jako parametr ogólny.
class SleepNightDiffCallback : DiffUtil.ItemCallback<SleepNight>() {
}
- Umieść kursor w nazwie klasy
SleepNightDiffCallback
. - Naciśnij
Alt+Enter
(Option+Enter
na Macu) i wybierz Wspieraj członków. - W wyświetlonym oknie kliknij lewym przyciskiem myszy, aby wybrać metody
areItemsTheSame()
iareContentsTheSame()
, a następnie kliknij OK.
Spowoduje to wygenerowanie namiotów wSleepNightDiffCallback
dla obu metod, jak pokazano poniżej.DiffUtil
wykorzystuje te 2 metody, aby ustalić, jak lista i elementy się zmieniły.
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.
}
- Zastąp
areItemsTheSame()
TODO
kodem, który sprawdza, czy dwa przekazywaneSleepNight
elementy,oldItem
inewItem
są takie same. Jeśli elementy mają tę samą wartośćnightId
, są tym samym elementem, więc ustaw wartośćtrue
. W przeciwnym razie zwróćfalse
.DiffUtil
wykorzystuje ten test, 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ź, czy wartościoldItem
inewItem
zawierają te same dane. W ramach tej funkcji zostaną sprawdzone wszystkie pola, ponieważSleepNight
jest klasą danych. Zajęcia wData
automatycznie określająequals
i kilka innych metod. JeślioldItem
inewItem
różnią się od siebie,DiffUtil
otrzyma ten kod z informacją, że element został zaktualizowany.
override fun areContentsTheSame(oldItem: SleepNight, newItem: SleepNight): Boolean {
return oldItem == newItem
}
Typowym wzorcem jest stosowanie listy RecyclerView
do wyświetlania listy, która się zmienia. Firma RecyclerView
udostępnia klasę adaptera ListAdapter
, która ułatwia stworzenie adaptera RecyclerView
opartego na liście.
ListAdapter
śledzi listę za Ciebie i powiadomi adapter o aktualizacji.
Krok 1. Zmień adapter, aby przedłużyć ListList.
- W pliku
SleepNightAdapter.kt
zmień podpis klasySleepNightAdapter
, aby wydłużyćListAdapter
. - Jeśli pojawi się taka prośba, zaimportuj plik
androidx.recyclerview.widget.ListAdapter
. - Dodaj
SleepNight
jako pierwszy argument doListAdapter
przedSleepNightAdapter.ViewHolder
. - Dodaj parametr
SleepNightDiffCallback()
jako parametr do konstruktora. Na podstawie tego elementu (ListAdapter
) ustali, co się zmieniło na liście. Gotowy podpis zajęćSleepNightAdapter
powinien wyglądać tak jak poniżej.
class SleepNightAdapter : ListAdapter<SleepNight, SleepNightAdapter.ViewHolder>(SleepNightDiffCallback()) {
- W ramach klasy
SleepNightAdapter
usuń poledata
, w tym ustawienie. Nie potrzebujesz już tej listy, boListAdapter
przechowuje ją dla Ciebie. - Usuń zastąpienie wartości
getItemCount()
, bo metodaListAdapter
implementuje tę metodę za Ciebie. - Aby usunąć błąd w elemencie
onBindViewHolder()
, zmień zmiennąitem
. Zamiast używaćdata
doitem
, wywołaj metodęgetItem(position)
dostarczoną przezListAdapter
.
val item = getItem(position)
Krok 2. Zaktualizuj listę za pomocą metody sendList()
Twój kod musi informować element ListAdapter
, że dostępna jest zmieniona lista. ListAdapter
udostępnia metodę submitList()
, która informuje ListAdapter
, że dostępna jest nowa wersja listy. Po wywołaniu tej metody ListAdapter
różni nową listę od starej i znajduje elementy, które zostały dodane, usunięte, przeniesione lub zmienione. Następnie ListAdapter
zaktualizuje elementy wyświetlane przez RecyclerView
.
- Otwórz aplikację
SleepTrackerFragment.kt
. - W
onCreateView()
na obserwatorzesleepTrackerViewModel
znajdź błąd, w którym występuje odwołanie do usuniętej zmiennejdata
. - Zastąp
adapter.data = it
połączeniem z numeremadapter.submitList(it)
. Zaktualizowany kod znajduje się poniżej.
sleepTrackerViewModel.nights.observe(viewLifecycleOwner, Observer {
it?.let {
adapter.submitList(it)
}
})
- Uruchom swoją aplikację. To działa szybciej, nawet jeśli lista jest mała.
W tym zadaniu korzystasz z tej samej metody co w poprzednich ćwiczeniach z programowania, aby skonfigurować wiązanie danych, a także wyeliminujesz wywołania findViewById()
.
Krok 1. Dodaj wiązanie danych do pliku układu
- Otwórz plik układu
list_item_sleep_night.xml
na karcie Tekst. - Umieść kursor na tagu
ConstraintLayout
i naciśnijAlt+Enter
(Option+Enter
na Macu). Otworzy się menu intencji. - Wybierz Konwertuj na układ wiązania danych. Spowoduje to opakowanie układu do formatu
<layout>
i dodanie tagu<data>
. - W razie potrzeby przewiń z góry do tagu
<data>
i zadeklaruj zmienną o nazwiesleep
. - Zmień nazwę usługi
type
naSleepNight
icom.example.android.trackmysleepquality.database.SleepNight
. Gotowy tag<data>
powinien wyglądać tak jak poniżej.
<data>
<variable
name="sleep"
type="com.example.android.trackmysleepquality.database.SleepNight"/>
</data>
- Aby wymusić utworzenie obiektu
Binding
, wybierz Build > Clean Project, a następnie wybierz Build > Rebuild Project. Jeśli nadal masz problemy, wybierz Plik > Unieważnij pamięć podręczną / uruchom ponownie. Obiekt wiązaniaListItemSleepNightBinding
wraz z powiązanym kodem zostanie dodany do wygenerowanych plików projektu.
Krok 2. Rozszerz układ elementu za pomocą wiązania danych
- Otwórz aplikację
SleepNightAdapter.kt
. - W klasie
ViewHolder
znajdź metodęfrom()
. - Usuń deklarację zmiennej
view
.
Kod do usuwania:
val view = layoutInflater
.inflate(R.layout.list_item_sleep_night, parent, false)
- Gdzie była zmienna
view
, zdefiniuj nową zmienną o nazwiebinding
, która zastępuje obiekt wiązaniaListItemSleepNightBinding
, jak pokazano poniżej. Wykonaj niezbędne importowanie obiektu wiązania.
val binding =
ListItemSleepNightBinding.inflate(layoutInflater, parent, false)
- Na końcu funkcji, zamiast zwracania
view
, zwróćbinding
.
return ViewHolder(binding)
- Aby go naprawić, umieść kursor na słowie
binding
. NaciśnijAlt+Enter
(Option+Enter
na Macu), by otworzyć menu intencji.
- Wybierz opcję Zmień parametr 'itemView' typ głównego konstruktora klasy 'ViewHolder' na 'ListItemSleepNightBinding'. Spowoduje to zaktualizowanie typu parametru klasy
ViewHolder
.
- Przewiń w górę do definicji klasy obiektu
ViewHolder
, aby zobaczyć zmianę w podpisie. Widzisz błąd w treściitemView
, bo w metodziefrom()
została zmieniona wartośćitemView
nabinding
.
W definicji klasyViewHolder
kliknij prawym przyciskiem myszy jedno z wystąpieńitemView
i wybierz Refaktor i Zmień nazwę. Zmień nazwę nabinding
. - Prefiks parametru konstruktora
binding
dodaj do elementuval
, aby ustawić go jako właściwość. - W wywołaniu klasy nadrzędnej
RecyclerView.ViewHolder
zmień parametr zbinding
nabinding.root
. Musisz przekazaćView
, abinding.root
jest głównym elementemConstraintLayout
w układzie elementu. - Ukończona deklaracja zajęć powinna wyglądać jak kod poniżej.
class ViewHolder private constructor(val binding: ListItemSleepNightBinding) : RecyclerView.ViewHolder(binding.root){
Zobaczysz też błąd w połączeniach z findViewById()
i naprawisz to.
Krok 3. Zastąp funkcję FindViewById()
Możesz teraz zaktualizować właściwości sleepLength
, quality
i qualityImage
, aby korzystały z obiektu binding
zamiast findViewById()
.
- Aby zmienić widok danych obiektu
binding
, zmień inicjacje obiektówsleepLength
,qualityString
iqualityImage
, jak pokazano poniżej. Od tego momentu kod nie powinien już podawać błędów.
val sleepLength: TextView = binding.sleepLength
val quality: TextView = binding.qualityString
val qualityImage: ImageView = binding.qualityImage
Po utworzeniu obiektu wiązania nie musisz już definiować właściwości sleepLength
, quality
ani qualityImage
. DataBinding
przechowuje w pamięci podręcznej wyszukiwania, więc nie trzeba deklarować tych właściwości.
- Kliknij prawym przyciskiem myszy nazwy właściwości
sleepLength
,quality
iqualityImage
. Wybierz Fact > Inline lub naciśnijControl+Command+N
(Option+Command+N
na Macu). - Uruchom aplikację. Jeśli zauważysz błędy, być może trzeba będzie wyczyścić i utworzyć ponownie projekt.
W tym zadaniu uaktualnisz aplikację, by korzystała z wiązania danych z adapterami wiązań, aby ustawiać dane w widokach.
W poprzednim ćwiczeniu z programowania użyto klasy Transformations
, aby utworzyć LiveData
i wygenerować sformatowane ciągi znaków do wyświetlenia w widokach tekstowych. Jeśli jednak chcesz utworzyć powiązanie różnych typów lub złożonych typów, możesz udostępnić adaptery wiązania, by ułatwić wiązanie danych. Adaptery to adaptery, które pobierają dane i przekształcają je w element, za pomocą którego ta funkcja może powiązać widok, np. tekst lub obraz.
Wdróżesz trzy adaptery: po jednym dla obrazu wysokiej jakości i jeden dla każdego pola tekstowego. W skrócie: aby zadeklarować adapter wiązania, musisz zdefiniować metodę, która wykorzystuje element i widok, i dodać do nich adnotacje za pomocą @BindingAdapter
. W treści metody przeprowadzasz przekształcenie. W Kotlin można napisać adapter wiązania jako funkcję rozszerzenia w klasie widoku danych, która odbiera dane.
Krok 1. Utwórz adaptery wiązań
Pamiętaj, że w tym kroku musisz zaimportować wiele zajęć. Nie będą one wywoływane pojedynczo.
- Otwórz aplikację
SleepNightAdapater.kt
. - W klasie
ViewHolder
znajdź metodębind()
i przypomnij sobie, jak działa. Pobierz kod, który oblicza wartościbinding.sleepLength
,binding.quality
ibinding.qualityImage
, i użyj go w adapterze. Na razie pozostaw kod bez zmian – przenieś go w późniejszym kroku. - W pakiecie
sleeptracker
utwórz i otwórz plik o nazwieBindingUtils.kt
. - Zadeklaruj funkcję rozszerzenia w
TextView
o nazwiesetSleepDurationFormatted
i przekażSleepNight
. Ta funkcja będzie adapterem do obliczania i formatowania czasu trwania snu.
fun TextView.setSleepDurationFormatted(item: SleepNight) {}
- W treści
setSleepDurationFormatted
utwórz powiązanie danych z widokiem danych, tak jak w narzędziuViewHolder.bind()
. WywołajconvertDurationToFormatted()
, a następnie ustawtext
wTextView
na sformatowany tekst. (To jest funkcja rozszerzenia wTextView
, więc masz bezpośredni dostęp do właściwościtext
).
text = convertDurationToFormatted(item.startTimeMilli, item.endTimeMilli, context.resources)
- Aby poinformować wiązanie danych o tym adapterze, dodaj do funkcji adnotacje funkcji
@BindingAdapter
. - Ta funkcja jest adapterem atrybutu
sleepDurationFormatted
, więc przekażsleepDurationFormatted
jako argument do@BindingAdapter
.
@BindingAdapter("sleepDurationFormatted")
- Drugi adapter ustawia jakość snu na podstawie wartości obiektu
SleepNight
. Utwórz funkcję rozszerzenia o nazwiesetSleepQualityString()
w dniuTextView
i przekażSleepNight
. - W treści artykułu utwórz powiązanie danych z widokiem danych, tak jak w przypadku elementu
ViewHolder.bind()
. Zadzwoń do:convertNumericQualityToString
i ustawtext
. - Dodaj adnotację do funkcji
@BindingAdapter("sleepQualityString")
.
@BindingAdapter("sleepQualityString")
fun TextView.setSleepQualityString(item: SleepNight) {
text = convertNumericQualityToString(item.sleepQuality, context.resources)
}
- Trzeci adapter wiązania ustawia obraz w widoku obrazu. Utwórz funkcję rozszerzenia w
ImageView
i zadzwoń dosetSleepImage
, a następnie 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 aplikację
SleepNightAdapter.kt
. - Usuń wszystko z metody
bind()
, ponieważ możesz teraz użyć wiązania danych i nowych adapterów, aby to zrobić.
fun bind(item: SleepNight) {
}
- W ramach
bind()
przypisz sen do:item
, ponieważ musisz wskazać obiekt wiążący dotyczący nowego elementuSleepNight
.
binding.sleep = item
- Poniżej tego wiersza dodaj
binding.executePendingBindings()
. To wywołanie to optymalizacja, która wymaga, aby wiązanie danych zostało natychmiast wykonane. Zawsze warto wywoływać interfejsexecutePendingBindings()
, gdy używasz adapterów wiązania wRecyclerView
, bo może to nieco zwiększyć rozmiar widoków.
binding.executePendingBindings()
Krok 3. Dodaj wiązania do układu XML
- Otwórz aplikację
list_item_sleep_night.xml
. - W polu
ImageView
dodaj właściwośćapp
o tej samej nazwie co adapter wiążący, który ustawia obraz. Przekaż zmiennąsleep
zgodnie z poniższym opisem.
Ta właściwość tworzy połączenie między widokiem danych a obiektem wiązania za pomocą adaptera. Jeśli nastąpi wywołanie funkcjisleepImage
, adapter dostosuje dane zSleepNight
.
app:sleepImage="@{sleep}"
- Zrób to samo w widokach tekstu
sleep_length
iquality_string
. Za każdym razem, gdy użyto odniesieniasleepDurationFormatted
lubsleepQualityString
, adaptery dostosowują dane zSleepNight
.
app:sleepDurationFormatted="@{sleep}"
app:sleepQualityString="@{sleep}"
- Uruchom aplikację. Działa ona dokładnie tak samo jak wcześniej. Adaptery wiążą się z całą pracą nad formatowaniem i aktualizowaniem widoków po zmianie danych, upraszczając
ViewHolder
i ulepszając kod znacznie lepiej niż dotychczas.
W przypadku kilku ostatnich ćwiczeń ta sama lista została wyświetlona. Została ona zaprojektowana tak, aby pokazać Ci, że interfejs Adapter
umożliwia projektowanie Twojego kodu na wiele różnych sposobów. Im bardziej złożony kod, tym większe znaczenie ma jego architektura. W aplikacjach produkcyjnych te wzorce i inne są używane w RecyclerView
. Wzorce działają prawidłowo, a każdy z nich ma swoje zalety. Wybór zależy od tego, co tworzysz.
Gratulacje! Jesteś na dobrej drodze, by opanować grę RecyclerView
na Androidzie.
Projekt na Android Studio: RecyclerViewDiffUtilDataBinding.
DiffUtil
:
RecyclerView
ma klasęDiffUtil
, która służy do obliczania różnic między 2 listami.- Klasa
DiffUtil
ma klasęItemCallBack
, którą wydłużasz, aby określić różnicę między 2 listami. - W klasie
ItemCallback
musisz zastąpić metodyareItemsTheSame()
iareContentsTheSame()
.
ListAdapter
:
- Aby bezpłatnie zarządzać listą, możesz użyć klasy
ListAdapter
zamiastRecyclerView.Adapter
. Jeśli jednak używaszListAdapter
, musisz przygotować własny adapter dla innych układów, dlatego to ćwiczenie ćwiczeń pokazuje, jak to zrobić. - Aby otworzyć menu intencji w Android Studio, umieść kursor na dowolnym elemencie kodu i naciśnij
Alt+Enter
(Option+Enter
na Macu). To menu jest szczególnie przydatne w przypadku refaktoryzacji kodu i tworzenia wycinków do implementacji metod. Sposób obsługi menu zależy od kontekstu – musisz go dokładnie umieścić na kursoru.
Powiązanie danych:
- Wiązanie danych w układzie elementu umożliwia powiązanie danych z widokami.
Adaptery wiążące:
- Wcześniej do tworzenia ciągów danych na podstawie tych danych użyto
Transformations
. Jeśli chcesz powiązać dane różnych lub złożonych typów, użyj adapterów wiązań, by ułatwić ich używanie. - Aby zadeklarować adapter wiązania, zdefiniuj metodę, która akceptuje element i widok, i dodaj adnotację do metody metodą
@BindingAdapter
. W Kotlin można zapisać adapter wiązania jako funkcję rozszerzenia wView
. Przekaż nazwę właściwości adaptowanej przez adapter. Przykład:
@BindingAdapter("sleepDurationFormatted")
- W układzie XML ustaw właściwość
app
o tej samej nazwie co adapter wiążący. Przekaż zmienną na podstawie danych. Przykład:
.app:sleepDurationFormatted="@{sleep}"
Kursy Udacity:
Dokumentacja dla programistów Androida:
- Tworzenie listy za pomocą widoku RecyclerView
RecyclerView
DiffUtil
- Biblioteka wiązania danych
- Adaptery wiążące
notifyDataSetChanged()
Transformations
Inne zasoby:
Ta sekcja zawiera listę możliwych zadań domowych dla uczniów, którzy pracują w ramach tego ćwiczenia w ramach kursu prowadzonego przez nauczyciela. To nauczyciel może wykonać te czynności:
- W razie potrzeby przypisz zadanie domowe.
- Poinformuj uczniów, jak przesyłać zadania domowe.
- Oceń projekty domowe.
Nauczyciele mogą wykorzystać te sugestie tak długo, jak chcą lub chcą, i mogą przypisać dowolne zadanie domowe.
Jeśli samodzielnie wykonujesz te ćwiczenia z programowania, możesz sprawdzić swoją wiedzę w tych zadaniach domowych.
Odpowiedz na te pytania
Pytanie 1
Które z poniższych działań są konieczne do korzystania z DiffUtil
? Wybierz wszystkie pasujące odpowiedzi.
▢ Rozszerzenie klasy ItemCallBack
.
▢ Zastąp areItemsTheSame()
.
▢ Zastąp areContentsTheSame()
.
▢ Do śledzenia różnic między elementami używaj wiązania danych.
Pytanie 2
Które z poniższych stwierdzeń na temat adapterów wiązań jest prawdziwe?
▢ Adapter wiążący to funkcja opatrzona adnotacją @BindingAdapter
.
▢ Użyj adaptera wiązania, aby oddzielić formatowanie danych od widoku.
▢ Jeśli chcesz używać adapterów wiązań, musisz użyć znacznika RecyclerViewAdapter
.
▢ Adaptery wiązania są dobrym rozwiązaniem, gdy chcesz przekształcić złożone dane.
Pytanie 3
Kiedy lepiej użyć Transformations
zamiast adaptera wiążącego? Wybierz wszystkie pasujące odpowiedzi.
▢ Twoje dane są proste;
▢ Formatowanie ciągu znaków.
▢ Twoja lista jest bardzo długa.
▢ ViewHolder
zawiera tylko jeden widok.
Rozpocznij następną lekcję: