Ten przewodnik uzupełnia omówienie biblioteki tymczasowej, w którym wyjaśnia, jak przedstawiać użytkownikom listy informacji w interfejsie aplikacji, zwłaszcza w przypadku zmiany tych informacji.
Łączenie interfejsu użytkownika z modelem widoku
Możesz połączyć wystąpienie LiveData<PagedList>
z PagedListAdapter
, jak pokazano w tym fragmencie kodu:
Kotlin
class ConcertActivity : AppCompatActivity() { private val adapter = ConcertAdapter() // Use the 'by viewModels()' Kotlin property delegate // from the activity-ktx artifact private val viewModel: ConcertViewModel by viewModels() override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState); viewModel.concerts.observe(this, Observer { adapter.submitList(it) }) } }
Java
public class ConcertActivity extends AppCompatActivity { private ConcertAdapter adapter = new ConcertAdapter(); private ConcertViewModel viewModel; @Override public void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); viewModel = new ViewModelProvider(this).get(ConcertViewModel.class); viewModel.concertList.observe(this, adapter::submitList); } }
Gdy źródła danych udostępniają nowe instancje PagedList
, aktywność wysyła te obiekty do adaptera. Implementacja PagedListAdapter
określa sposób obliczania aktualizacji i automatycznie obsługuje stronicowanie i różnicowanie list. Dlatego ViewHolder
musi powiązać tylko konkretny udostępniony element:
Kotlin
class ConcertAdapter() : PagedListAdapter<Concert, ConcertViewHolder>(DIFF_CALLBACK) { override fun onBindViewHolder(holder: ConcertViewHolder, position: Int) { val concert: Concert? = getItem(position) // Note that "concert" is a placeholder if it's null. holder.bindTo(concert) } companion object { private val DIFF_CALLBACK = ... // See Implement the diffing callback section. } }
Java
public class ConcertAdapter extends PagedListAdapter<Concert, ConcertViewHolder> { protected ConcertAdapter() { super(DIFF_CALLBACK); } @Override public void onBindViewHolder(@NonNull ConcertViewHolder holder, int position) { Concert concert = getItem(position); // Note that "concert" can be null if it's a placeholder. holder.bindTo(concert); } private static DiffUtil.ItemCallback<Concert> DIFF_CALLBACK = ... // See Implement the diffing callback section. }
PagedListAdapter
obsługuje zdarzenia wczytywania strony za pomocą obiektu PagedList.Callback
. Gdy użytkownik przewija stronę, PagedListAdapter
wywołuje metodę PagedList.loadAround()
, by przekazać informacje do bazowego komponentu PagedList
, które wskazują, które elementy należy pobrać z DataSource
.
Implementowanie różniącego się wywołania zwrotnego
Poniższy przykład pokazuje ręczną implementację funkcji areContentsTheSame()
, która porównuje odpowiednie pola obiektów:
Kotlin
private val DIFF_CALLBACK = object : DiffUtil.ItemCallback<Concert>() { // The ID property identifies when items are the same. override fun areItemsTheSame(oldItem: Concert, newItem: Concert) = oldItem.id == newItem.id // If you use the "==" operator, make sure that the object implements // .equals(). Alternatively, write custom data comparison logic here. override fun areContentsTheSame( oldItem: Concert, newItem: Concert) = oldItem == newItem }
Java
private static DiffUtil.ItemCallback<Concert> DIFF_CALLBACK = new DiffUtil.ItemCallback<Concert>() { @Override public boolean areItemsTheSame(Concert oldItem, Concert newItem) { // The ID property identifies when items are the same. return oldItem.getId() == newItem.getId(); } @Override public boolean areContentsTheSame(Concert oldItem, Concert newItem) { // Don't use the "==" operator here. Either implement and use .equals(), // or write custom data comparison logic here. return oldItem.equals(newItem); } };
Adapter zawiera definicję porównywania elementów, dlatego automatycznie wykrywa zmiany w tych elementach po wczytaniu nowego obiektu PagedList
. W efekcie adapter aktywuje wydajne animacje elementów w obiekcie RecyclerView
.
Różnice w przypadku użycia innego typu przejściówki
Jeśli nie zdecydujesz się na dziedziczenie z PagedListAdapter
, np. gdy używasz biblioteki, która ma własny adapter, nadal możesz korzystać z funkcji różnicowania adaptera biblioteki, pracując bezpośrednio z obiektem AsyncPagedListDiffer
.
Umieszczanie obiektów zastępczych w interfejsie
Jeśli chcesz, aby przed zakończeniem pobierania danych aplikacja wyświetlała listę, możesz pokazać użytkownikom zastępcze elementy listy. PagedList
obsługuje ten przypadek, prezentując dane elementu listy jako null
, dopóki nie zostaną one wczytane.
Obiekty zastępcze mają te zalety:
- Obsługa pasków przewijania:
PagedList
podaje liczbę elementów listy w elemenciePagedListAdapter
. Ta informacja umożliwia adapterowi narysowanie paska przewijania z pełnym rozmiarem listy. Przy wczytywaniu nowych stron pasek przewijania nie skacze, ponieważ lista nie zmienia się. - Wskaźnik wczytywania nie jest wymagany: rozmiar listy jest już znany, więc nie trzeba powiadamiać użytkowników o wczytywaniu kolejnych elementów. Symbole zastępcze same w sobie przekazują te informacje.
Zanim jednak dodasz obsługę obiektów zastępczych, pamiętaj o tych warunkach wstępnych:
- Wymaga obliczonego zbioru danych: instancje
DataSource
z biblioteki trwałości sal mogą skutecznie zliczać elementy. Jeśli jednak korzystasz z niestandardowego rozwiązania do pamięci lokalnej lub architektury danych obejmującej tylko sieć, określenie, ile elementów składa się na zbiór danych, może być kosztowne, a nawet niemożliwe. - Wymaga adaptera, by uwzględnić niewczytane elementy: adapter lub mechanizm do prezentacji, którego używasz do przygotowywania listy pod kątem inflacji do obsługi pustych elementów listy. Gdy na przykład łączysz dane z elementem
ViewHolder
, musisz podać wartości domyślne reprezentujące dane niewczytane. - Wymaga wyświetleń elementów w tym samym rozmiarze: jeśli rozmiary elementów listy mogą się zmieniać w zależności od ich treści (np. aktualizacji w sieciach społecznościowych), przenikanie między elementami nie wygląda dobrze. W tym przypadku zdecydowanie zalecamy wyłączenie obiektów zastępczych.
Prześlij opinię
Podziel się z nami swoją opinią i pomysłami, korzystając z tych zasobów:
- Śledzenie problemów
- Zgłoś problemy, żebyśmy mogli naprawić błędy.
Dodatkowe materiały
Więcej informacji o bibliotece stronicowania znajdziesz w tych materiałach:
Próbki
Ćwiczenia z programowania
Filmy
- Android Jetpack: zarządzaj nieskończonymi listami za pomocą RecyclerView i Paging (Google I/O 2018)
- Android Jetpack: pager
Polecane dla Ciebie
- Uwaga: tekst linku jest wyświetlany, gdy JavaScript jest wyłączony
- Omówienie biblioteki na etapie 2
- Migrate to Paging 3 (Migracja do strony 3)
- Gromadzenie danych z podziałem na strony