遷移至 Paging 3 (Views)

概念和 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 也可以搭配 asPagingSourceFactory 方法使用舊版 DataSource 物件。這表示您有下列遷移選項:

  • 您可以將 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 密封類別,其中包含每種載入類型的子類別。如果您需要區分 load 方法中的載入類型,請檢查傳遞的 LoadParams 子類別為何:LoadParams.Refresh, LoadParams.PrependLoadParams.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 導入的所有必要變更,以便在 Paging 3 中使用 PagerPagingData

PagedListBuilder 類別

PagingData 替換 Paging 2 中現有的 PagedList。如要遷移至 PagingData,您必須更新下列項目:

  • Paging 設定已從 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 類別。

分頁 2 會使用 PagedListAdapterPagedList 繫結至 RecyclerView。在 Paging 3 中,PagingData 會取代 PagedList

Paging 3 會提供 PagingDataAdapter 來處理新的 PagingData 回應式串流。除此之外,PagedListAdapterPagingDataAdapter 擁有相同的介面。如要從 PagedListAdapter 遷移至 PagingDataAdapter,請改為變更 PagedListAdapter 的導入來擴充 PagingDataAdapter

如要進一步瞭解 PagingDataAdapter,請參閱「定義 RecyclerView 轉接程式」。

AsyncPagedListDiffer

如果您目前透過 AsyncPagedListDiffer 使用自訂的 RecyclerView.Adapter 導入,請改為遷移導入以使用 Paging 3 提供的 AsyncPagingDataDiffer

Kotlin

AsyncPagingDataDiffer(diffCallback, listUpdateCallback)

Java (RxJava)

new AsyncPagingDataDiffer(diffCallback, listUpdateCallback);

Java (Guava/LiveData)

new AsyncPagingDataDiffer(diffCallback, listUpdateCallback);