迁移到 Paging 3(视图)

概念和 Jetpack Compose 实现

Paging 3 与旧版 Paging 库存在很大区别。 此版本提供了增强型功能,还解决了使用 Paging 2 时常见的问题。如果您的应用已在使用旧版 Paging 库,请阅读本页面,详细了解如何迁移到 Paging 3。

如果 Paging 3 是您在 应用中使用的第一个 Paging 库版本,请参阅加载并显示分页数据,了解基本用法信息。

迁移到 Paging 3 的优势

Paging 3 包含旧版库中没有的下列功能:

  • 为 Kotlin 协程和流程提供一流的支持。
  • 支持使用 RxJava Single 或 Guava ListenableFuture 基元进行异步加载。
  • 针对自适应界面设计的内置加载状态和错误信号,包括重试和刷新功能。
  • 改进了代码库层,包括取消支持和简化的数据源界面。
  • 改进了表示层、列表分隔符、自定义页面转换和加载状态页眉和页脚。

将应用迁移到 Paging 3

为了完全迁移到 Paging 3,您必须从 Paging 2 迁移所有三个主要组件:

  • DataSource
  • PagedList
  • PagedListAdapter

不过,某些 Paging 3 组件向后兼容旧版 Paging。具体来说,Paging 3 中的 PagingSource API 可以 是旧版中 LivePagedListBuilderRxPagedListBuilder 的数据源。同样,Pager API 可以使用旧版 DataSource 对象处理 asPagingSourceFactory 方法。这意味着,您有以下迁移选项:

  • 您可以将 DataSource 迁移到 PagingSource,但让 Paging 实现的其余部分保持不变。
  • 您可以迁移 PagedListPagedListAdapter,但仍使用 旧版 DataSource API。
  • 您可以迁移整个 Paging 实现以将应用完全迁移到 Paging 3。

本页中的各个部分介绍了如何迁移应用每个层上的 Paging 组件。

迁移概览

如需完全迁移到 Paging 3,同时保留 RecyclerView 实现,您必须更新以下组件:

Paging 2 组件

Paging 3 替换项

PageKeyedDataSource

PagingSource

PagedListAdapter

PagingDataAdapter

LivePagedListBuilder

Pager

BoundaryCallback

RemoteMediator

DataSource

本部分介绍迁移旧版 Paging 实现以使用 PagingSource 所需的更改。

Paging 2 中的 PageKeyedDataSource, PositionalDataSourceItemKeyedDataSource 都合并到了 Paging 3 中的 PagingSource API 中。所有旧版 API 类中的加载方法都合并到了 PagingSource 中的单个 load 方法中。这减少了代码重复,因为旧版 API 类的实现中加载方法的大部分逻辑通常是相同的。

在 Paging 3 中,所有加载方法参数被一个 LoadParams 密封类替代,该类中包含了每个加载类型所对应的子类。如果您需要在 方法中区分加载类型,请检查传入的 LoadParams的哪个子类:LoadParams.Refresh, LoadParams.PrependLoadParams.Appendload

如需详细了解如何实现 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 实现以使用 Paging 3 中的 PagerPagingData 所需的所有更改。

PagedListBuilder

PagingData 替换了 Paging 2 中现有的 PagedList。为了迁移到 PagingData,您必须完成以下更新:

  • 将分页配置从 PagedList.Config 变为 PagingConfig
  • LivePagedListBuilderRxPagedListBuilder 合并成单个 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);

如需详细了解如何使用 Paging 3 设置 PagingData 对象的响应式流,请参阅设置 PagingData 流

PagedListAdapter

本部分介绍迁移旧版 Paging 实现以使用 Paging 3 中的 PagingDataAdapterAsyncPagingDataDiffer 类所需的所有更改。

Paging 2 使用 PagedListAdapterPagedList 绑定到 RecyclerView。在 Paging 3 中,PagingData 取代了 PagedList

Paging 3 提供 PagingDataAdapter 来处理新的 PagingData 响应式 流。否则,PagedListAdapterPagingDataAdapter 将具有相同的接口。如需从 PagedListAdapter 迁移到 PagingDataAdapter,请更改 PagedListAdapter 的实现,以扩展 PagingDataAdapter

如需详细了解 PagingDataAdapter,请参阅 定义 RecyclerView 适配器

AsyncPagedListDiffer

如果您目前将自定义 RecyclerView.Adapter 实现与 AsyncPagedListDiffer 搭配使用,请迁移您的实现以使用 Paging 3 中提供的 AsyncPagingDataDiffer

Kotlin

AsyncPagingDataDiffer(diffCallback, listUpdateCallback)

Java (RxJava)

new AsyncPagingDataDiffer(diffCallback, listUpdateCallback);

Java (Guava/LiveData)

new AsyncPagingDataDiffer(diffCallback, listUpdateCallback);