Перейти к постраничной навигации (3 представления)

Концепции и реализация Jetpack Compose

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

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

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

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

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

Переведите ваше приложение на Paging 3.

Для полного перехода на систему пейджинга 3 необходимо перенести все три основных компонента из системы пейджинга 2:

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

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

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

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

Обзор миграции

Для полного перехода на Paging 3 с сохранением реализации RecyclerView необходимо обновить следующие компоненты:

Компонент пейджинга 2

Замена пейджинга 3

PageKeyedDataSource

PagingSource

PagedListAdapter

PagingDataAdapter

LivePagedListBuilder

Pager

BoundaryCallback

RemoteMediator

Классы DataSource

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

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

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

Чтобы узнать больше о реализации PagingSource , см. раздел «Определение источника данных» .

Клавиши обновления

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

Java (RxJava)

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

Java (Guava/LiveData)

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

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 соответственно.

Java (RxJava)

// 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 (Guava/LiveData)

// 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» .

PagedListAdapter

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

В Paging 2 для привязки PagedList к RecyclerView используется PagedListAdapter . В Paging 3 PagedList заменяется на PagingData .

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

Чтобы узнать больше о PagingDataAdapter , см. раздел «Определение адаптера RecyclerView» .

AsyncPagedListDiffer

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

Котлин

AsyncPagingDataDiffer(diffCallback, listUpdateCallback)

Java (RxJava)

new AsyncPagingDataDiffer(diffCallback, listUpdateCallback);

Java (Guava/LiveData)

new AsyncPagingDataDiffer(diffCallback, listUpdateCallback);