Migrate to Paging 3 (Migracja do strony 3)

Strona 3 znacznie różni się od wcześniejszych wersji biblioteki stronicowania. Ta wersja udostępnia ulepszone funkcje i rozwiązuje typowe problemy z używaniem Stronowania 2. Jeśli Twoja aplikacja korzysta już z wcześniejszej wersji biblioteki stronicowania, przeczytaj tę stronę, aby dowiedzieć się więcej o migracji do etapu 3.

Jeśli Paging 3 jest pierwszą wersją biblioteki stronicowania, której używasz w aplikacji, przeczytaj sekcję Wczytywanie i wyświetlanie danych z podziałem na strony, aby uzyskać podstawowe informacje o jej użyciu.

Zalety przejścia na stronę Paging 3

Strona 3 obejmuje te funkcje, które nie były dostępne we wcześniejszych wersjach biblioteki:

  • Pierwsza klasa wsparcia dla współprogramów Kotlin i Flow.
  • Obsługa ładowania asynchronicznego przy użyciu elementów podstawowych RxJava Single lub ListenableFuture Guava.
  • Wbudowane sygnały stanu wczytywania i błędów na potrzeby elastycznego projektowania interfejsu, w tym funkcje ponawiania próby i odświeżania.
  • Ulepszenia warstwy repozytorium, w tym obsługa anulowania i uproszczony interfejs źródła danych.
  • Ulepszenia warstwy prezentacji, separatorów list, niestandardowych przekształceń stron oraz nagłówków i stopek stanu wczytywania.

Migracja aplikacji do strony Paging 3

Aby w pełni przejść na stronę 3, musisz przenieść wszystkie 3 główne komponenty ze strony 2:

  • DataSource zajęcia
  • PagedList
  • PagedListAdapter

Niektóre komponenty strony 3 są jednak zgodne wstecznie z poprzednimi wersjami strony. W szczególności źródło danych LivePagedListBuilder i RxPagedListBuilder ze starszych wersji interfejsu API PagingSource z strony Stronowania 3 może być źródłem danych. Podobnie interfejs Pager API może używać starszych obiektów DataSource za pomocą metody asPagingSourceFactory(). Oznacza to, że masz te opcje migracji:

  • Możesz przenieść DataSource do PagingSource, ale resztę implementacji pozostawiasz bez zmian.
  • Możesz przenieść PagedList i PagedListAdapter, ale nadal możesz używać starszego interfejsu API DataSource.
  • Aby przeprowadzić pełną migrację aplikacji do strony Paging 3, możesz przenieść całą implementację strony.

W sekcjach na tej stronie dowiesz się, jak przenieść komponenty strony w poszczególnych warstwach aplikacji.

Klasy DataSource

W tej sekcji opisano wszystkie zmiany niezbędne do przeniesienia starszej implementacji stronicowania na interfejs PagingSource.

PageKeyedDataSource, PositionalDataSource i ItemKeyedDataSource ze strony 2 są połączone w interfejs API PagingSource na stronie 3. Metody wczytywania ze wszystkich starych klas interfejsu API są połączone w PagingSource w jedną metodę load(). Zmniejsza to duplikowanie kodu, ponieważ większość logiki w metodach wczytywania w implementacjach starych klas interfejsu API jest często identyczna.

Na stronie Stron 3 wszystkie parametry metody wczytywania są zastępowane klasą LoadParams, która zawiera podklasy poszczególnych typów wczytywania. Jeśli musisz rozróżnić typy wczytywania w metodzie load(), sprawdź, która podklasa klasy LoadParams została przekazana w klasie LoadParams.Refresh, LoadParams.Prepend lub LoadParams.Append.

Więcej informacji o implementowaniu funkcji PagingSource znajdziesz w sekcji Definiowanie źródła danych.

Odśwież klucze

Implementacje funkcji PagingSource muszą określać sposób wznawiania odświeżania od środka wczytywanych danych stron. Aby to zrobić, zaimplementuj getRefreshKey(), aby zmapować prawidłowy klucz początkowy, używając state.anchorPosition jako ostatnio dostępnego indeksu.

Kotlin

// Replaces ItemKeyedDataSource.
override fun getRefreshKey(state: PagingState): String? {
  return state.anchorPosition?.let { anchorPosition ->
    state.getClosestItemToPosition(anchorPosition)?.id
  }
}

// Replacing PositionalDataSource.
override fun getRefreshKey(state: PagingState): Int? {
  return state.anchorPosition
}

Java

// Replaces ItemKeyedDataSource.
@Nullable
@Override
String getRefreshKey(state: PagingState) {
  Integer anchorPosition = state.anchorPosition;
  if (anchorPosition == null) {
    return null;
  }

  return state.getClosestItemToPosition(anchorPosition);
}

// Replaces PositionalDataSource.
@Nullable
@Override
Integer getRefreshKey(state: PagingState) {
  return state.anchorPosition;
}

Java

// Replacing ItemKeyedDataSource.
@Nullable
@Override
String getRefreshKey(state: PagingState) {
  Integer anchorPosition = state.anchorPosition;
  if (anchorPosition == null) {
    return null;
  }

  return state.getClosestItemToPosition(anchorPosition);
}

// Replacing PositionalDataSource.
@Nullable
@Override
Integer getRefreshKey(state: PagingState) {
  return state.anchorPosition;
}

Wyświetlenie listy przekształceń

W starszych wersjach biblioteki stronicowania przekształcanie danych z podziałem na strony odbywa się za pomocą tych metod:

  • DataSource.map()
  • DataSource.mapByPage()
  • DataSource.Factory.map()
  • DataSource.Factory.mapByPage()

Na stronie 3 wszystkie przekształcenia są stosowane jako operatory na stronie PagingData. Jeśli do przekształcenia listy stron używasz dowolnej z metod z poprzedniej listy, podczas tworzenia obiektu Pager za pomocą nowego PagingSource musisz przenieść logikę przekształcenia z zasobu DataSource do PagingData.

Więcej informacji o stosowaniu przekształceń do danych stronicowanych za pomocą strony 3 znajdziesz w artykule Przekształcanie strumieni danych.

Lista stron

W tej sekcji opisujemy wszystkie zmiany niezbędne do przeniesienia starszej implementacji Stronniczej, tak aby korzystała z elementów Pager i PagingData na stronie Paging 3.

Klasy PagedListBuilder

PagingData zastępuje istniejące PagedList strony z stroną 2. Aby przeprowadzić migrację do PagingData, musisz zaktualizować te dane:

  • Konfiguracja strony została przeniesiona z PagedList.Config do PagingConfig.
  • Jednostki LivePagedListBuilder i RxPagedListBuilder zostały połączone w jedną klasę Pager.
  • Pager ujawnia możliwą do obserwowania Flow<PagingData> z właściwością .flow. Warianty RxJava i LiveData są również dostępne jako właściwości rozszerzenia, które są wywoływane z języka Java za pomocą metod statycznych i dostarczane odpowiednio z modułów paging-rxjava* i paging-runtime.

Kotlin

val flow = Pager(
  // Configure how data is loaded by passing additional properties to
  // PagingConfig, such as prefetchDistance.
  PagingConfig(pageSize = 20)
) {
  ExamplePagingSource(backend, query)
}.flow
  .cachedIn(viewModelScope)

Java

// CoroutineScope helper provided by the lifecycle-viewmodel-ktx artifact.
CoroutineScope viewModelScope = ViewModelKt.getViewModelScope(viewModel);
Pager<Integer, User> pager = Pager<>(
  new PagingConfig(/* pageSize = */ 20),
  () -> ExamplePagingSource(backend, query));

Flowable<PagingData<User>> flowable = PagingRx.getFlowable(pager);
PagingRx.cachedIn(flowable, viewModelScope);

Java

// CoroutineScope helper provided by the lifecycle-viewmodel-ktx artifact.
CoroutineScope viewModelScope = ViewModelKt.getViewModelScope(viewModel);
Pager<Integer, User> pager = Pager<>(
  new PagingConfig(/* pageSize = */ 20),
  () -> ExamplePagingSource(backend, query));

PagingLiveData.cachedIn(PagingLiveData.getLiveData(pager), viewModelScope);

Więcej informacji o konfigurowaniu reaktywnego strumienia obiektów PagingData za pomocą strony Paging 3 znajdziesz w sekcji Konfigurowanie strumienia danych PagingData.

BoundaryCallback w przypadku źródeł warstwowych

Na stronie 3 RemoteMediator zastępuje PagedList.BoundaryCallback jako moduł obsługi stronicowania z sieci i bazy danych.

Więcej informacji o używaniu RemoteMediator do przechodzenia z sieci i bazy danych na stronę z sieci i bazy danych w Paging 3 znajdziesz w ćwiczeniach z programowania dla stron na Androida.

Adapter PagedListAdapter

W tej sekcji opisujemy wszystkie zmiany niezbędne do przeniesienia starszej implementacji Stronniczej, tak aby korzystała z klas PagingDataAdapter lub AsyncPagingDataDiffer ze Stronu 3.

Strona 3 zapewnia interfejs PagingDataAdapter do obsługi nowych strumieni reaktywnych PagingData. W przeciwnym razie PagedListAdapter i PagingDataAdapter mają ten sam interfejs. Aby przeprowadzić migrację z PagedListAdapter do PagingDataAdapter, zmień implementację PagedListAdapter na PagingDataAdapter.

Więcej informacji o właściwości PagingDataAdapter znajdziesz w sekcji dotyczącej definiowania adaptera obiektu RecyclerView.

AsyncPagedListDiffer

Jeśli korzystasz obecnie z niestandardowej implementacji RecyclerView.Adapter w interfejsie AsyncPagedListDiffer, przenieś ją, aby używała interfejsu AsyncPagingDataDiffer podanego na stronie 3:

Kotlin

AsyncPagingDataDiffer(diffCallback, listUpdateCallback)

Java

new AsyncPagingDataDiffer(diffCallback, listUpdateCallback);

Java

new AsyncPagingDataDiffer(diffCallback, listUpdateCallback);

Dodatkowe materiały

Więcej informacji o bibliotece stronicowania znajdziesz w tych dodatkowych materiałach:

Ćwiczenia z programowania

Próbki