Перейти на страницу 3

Paging 3 существенно отличается от более ранних версий библиотеки Paging. Эта версия обеспечивает расширенные функциональные возможности и устраняет распространенные трудности при использовании Paging 2. Если ваше приложение уже использует более раннюю версию библиотеки Paging, прочтите эту страницу, чтобы узнать больше о переходе на Paging 3.

Если Paging 3 — это первая версия библиотеки подкачки, которую вы используете в своем приложении, см. раздел Загрузка и отображение постраничных данных для получения основной информации об использовании.

Преимущества перехода на Page 3

Paging 3 включает в себя следующие функции, которых не было в более ранних версиях библиотеки:

  • Первоклассная поддержка сопрограмм Kotlin и Flow.
  • Поддержка асинхронной загрузки с использованием примитивов RxJava Single или Guava ListenableFuture .
  • Встроенные сигналы состояния загрузки и ошибок для адаптивного дизайна пользовательского интерфейса, включая функции повтора и обновления.
  • Улучшения уровня репозитория, включая поддержку отмены и упрощенный интерфейс источника данных.
  • Улучшения уровня представления, разделителей списков, пользовательских преобразований страниц, а также верхних и нижних колонтитулов состояния загрузки.

Перенесите свое приложение на Paging 3

Чтобы полностью перейти на Paging 3, необходимо перенести все три основных компонента из Paging 2:

  • Классы DataSource
  • PagedList
  • PagedListAdapter

Однако некоторые компоненты Paging 3 обратно совместимы с предыдущими версиями Paging. В частности, API PagingSource из Paging 3 может быть источником данных для LivePagedListBuilder и RxPagedListBuilder из более старых версий. Аналогичным образом API Pager может использовать старые объекты DataSource с помощью метода asPagingSourceFactory() . Это означает, что у вас есть следующие варианты миграции:

  • Вы можете перенести свой DataSource в PagingSource , но оставить остальную часть реализации Paging без изменений.
  • Вы можете перенести PagedList и PagedListAdapter , но по-прежнему использовать старый API DataSource .
  • Вы можете перенести всю реализацию Paging, чтобы полностью перенести свое приложение на Paging 3.

В разделах на этой странице объясняется, как перенести компоненты подкачки на каждый уровень вашего приложения.

Классы источника данных

В этом разделе описаны все необходимые изменения для миграции старой реализации Paging на использование PagingSource .

PageKeyedDataSource , PositionalDataSource и ItemKeyedDataSource из Paging 2 объединены в PagingSource API в Paging 3. Методы загрузки всех старых классов API объединены в один метод load() в PagingSource . Это уменьшает дублирование кода, поскольку большая часть логики методов загрузки в реализациях старых классов API часто идентична.

Все параметры метода загрузки заменены в Paging 3 закрытым классом LoadParams , который включает подклассы для каждого типа загрузки. Если вам нужно различать типы загрузки в методе load() , проверьте, какой подкласс LoadParams был передан: LoadParams.Refresh , LoadParams.Prepend или LoadParams.Append .

Дополнительные сведения о реализации PagingSource см. в разделе Определение источника данных .

Обновить ключи

Реализации PagingSource должны определять, как обновления возобновляются с середины загруженных выгружаемых данных. Сделайте это, реализовав getRefreshKey() для сопоставления правильного начального ключа, используя state.anchorPosition в качестве индекса, к которому последний раз обращались.

Котлин

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

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

Ява

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

  return state.getClosestItemToPosition(anchorPosition);
}

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

Ява

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

  return state.getClosestItemToPosition(anchorPosition);
}

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

Список преобразований

В более старых версиях библиотеки подкачки преобразование выгружаемых данных основано на следующих методах:

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

В Paging 3 все преобразования применяются как операторы к PagingData . Если вы используете какой-либо из методов из предыдущего списка для преобразования выгружаемого списка, вам необходимо переместить логику преобразования из DataSource в PagingData при создании Pager с использованием нового PagingSource .

Дополнительные сведения о применении преобразований к постраничным данным с помощью Paging 3 см. в разделе Преобразование потоков данных .

PagedList

В этом разделе описаны все необходимые изменения для миграции старой реализации Paging на использование Pager и PagingData в Paging 3.

Классы PagedListBuilder

PagingData заменяет существующий PagedList из Paging 2. Для перехода на PagingData необходимо обновить следующее:

  • Конфигурация пейджинга перемещена из PagedList.Config в PagingConfig .
  • LivePagedListBuilder и RxPagedListBuilder объединены в один класс Pager .
  • Pager предоставляет наблюдаемый Flow<PagingData> со своим свойством .flow . Варианты RxJava и LiveData также доступны в качестве свойств расширения, которые можно вызвать из Java с помощью статических методов и получить из модулей paging-rxjava* и paging-runtime соответственно.

Котлин

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)

Ява

// 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);

Ява

// 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);

Дополнительные сведения о настройке реактивного потока объектов PagingData с помощью Paging 3 см. в разделе Настройка потока PagingData .

BoundaryCallback для многоуровневых источников

В Paging 3 RemoteMediator заменяет PagedList.BoundaryCallback в качестве обработчика пейджинга из сети и базы данных.

Дополнительные сведения об использовании RemoteMediator для пейджинга из сети и базы данных в Paging 3 см. в лаборатории кода Android Paging .

PagedListАдаптер

В этом разделе описаны все необходимые изменения для миграции старой реализации Paging на использование классов PagingDataAdapter или AsyncPagingDataDiffer из Paging 3.

Paging 3 предоставляет PagingDataAdapter для обработки новых реактивных потоков PagingData . В противном случае PagedListAdapter и PagingDataAdapter имеют одинаковый интерфейс. Чтобы перейти с PagedListAdapter на PagingDataAdapter , измените реализацию PagedListAdapter , чтобы вместо этого расширить PagingDataAdapter .

Дополнительные сведения о PagingDataAdapter см. в разделе Определение адаптера RecyclerView .

Асинкпажедлистдиффер

Если вы в настоящее время используете собственную реализацию RecyclerView.Adapter с AsyncPagedListDiffer , перенесите свою реализацию на использование AsyncPagingDataDiffer , представленного в Paging 3:

Котлин

AsyncPagingDataDiffer(diffCallback, listUpdateCallback)

Ява

new AsyncPagingDataDiffer(diffCallback, listUpdateCallback);

Ява

new AsyncPagingDataDiffer(diffCallback, listUpdateCallback);

Дополнительные ресурсы

Чтобы узнать больше о библиотеке подкачки, см. следующие дополнительные ресурсы:

Кодлабы

Образцы

{% дословно %} {% дословно %} {% дословно %} {% дословно %}