Di chuyển sang Paging 3

Paging 3 có sự khác biệt đáng kể so với các phiên bản thư viện Paging trước đó. Phiên bản này cung cấp chức năng nâng cao và giải quyết các vấn đề phổ biến khi sử dụng Paging 2. Nếu ứng dụng đang sử dụng phiên bản cũ hơn của thư viện Paging, hãy đọc trang này để tìm hiểu thêm về cách chuyển sang thư viện Phân trang 3.

Nếu Paging 3 là phiên bản đầu tiên của thư viện Paging được sử dụng trong ứng dụng, hãy xem bài viết Tải và hiển thị dữ liệu được phân trang để biết thông tin cơ bản về cách sử dụng.

Những lợi ích của việc chuyển sang Paging 3

Paging 3 bao gồm những tính năng mà các phiên bản thư viện trước đó chưa có:

  • Khả năng hỗ trợ hàng đầu cho các coroutine và Flow Kotlin.
  • Hỗ trợ tính năng tải không đồng bộ bằng cách sử dụng các nguyên hàm RxJava Single hoặc Guava ListenableFuture.
  • Trạng thái tải tích hợp và các tín hiệu lỗi cho thiết kế giao diện người dùng thích ứng, bao gồm chức năng thử lại và làm mới.
  • Những cải tiến đối với lớp kho lưu trữ, bao gồm khả năng hỗ trợ hành động huỷ và giao diện nguồn dữ liệu được đơn giản hoá.
  • Những cải tiến đối với tầng trình diễn, dấu phân cách danh sách, biến đổi trang tuỳ chỉnh, tiêu đề và chân trang trạng thái tải.

Di chuyển ứng dụng sang Paging 3

Để di chuyển hoàn toàn sang Paging 3, bạn phải di chuyển cả ba thành phần chính từ Paging 2:

  • Các lớp DataSource
  • PagedList
  • PagedListAdapter

Tuy nhiên, một số thành phần Paging 3 có khả năng tương thích ngược với các phiên bản Paging trước. Cụ thể, API PagingSource của Paging 3 có thể là nguồn dữ liệu cho LivePagedListBuilderRxPagedListBuilder từ các phiên bản cũ. Tương tự, API Pager có thể sử dụng các đối tượng DataSource cũ bằng phương thức asPagingSourceFactory(). Điều này có nghĩa là bạn có các cách di chuyển sau:

  • Bạn có thể di chuyển DataSource sang PagingSource nhưng không thay đổi phần còn lại của quá trình triển khai Paging.
  • Bạn có thể di chuyển PagedListPagedListAdapter nhưng vẫn sử dụng API DataSource cũ.
  • Bạn có thể di chuyển toàn bộ quá trình triển khai Paging để di chuyển hoàn toàn ứng dụng sang Paging 3.

Các phần trên trang này giải thích cách di chuyển các thành phần Paging trên mỗi lớp của ứng dụng.

Các lớp DataSource

Phần này mô tả tất cả các thay đổi cần thiết để di chuyển quá trình triển khai Paging cũ để sử dụng PagingSource.

PageKeyedDataSource, PositionalDataSourceItemKeyedDataSource từ Paging 2 đều được kết hợp vào API PagingSource trong Paging 3. Các phương thức tải từ tất cả các lớp API cũ được kết hợp thành một phương thức load() duy nhất trong PagingSource. Điều này giảm việc trùng lặp mã vì đa số logic của các phương thức tải trong quá trình triển khai các lớp API cũ giống nhau.

Trong Paging 3, tất cả các thông số phương thức tải được thay thế bằng một lớp kín LoadParams, bao gồm các lớp con cho mỗi loại tải. Nếu bạn cần phân biệt các loại tải trong phương thức load(), hãy kiểm tra lớp con nào của LoadParams sau đây đã được truyền: LoadParams.Refresh,LoadParams.Prepend hoặc LoadParams.Append.

Để tìm hiểu thêm về cách triển khai PagingSource, hãy xem bài viết Xác định nguồn dữ liệu.

Làm mới khoá

Các cách triển khai PagingSource phải xác định cách thức làm mới tiếp tục từ giữa dữ liệu tải đã phân trang. Thực hiện việc này bằng cách triển khai getRefreshKey() để ánh xạ khoá khởi động chính xác bằng cách sử dụng state.anchorPosition làm chỉ mục được truy cập gần đây nhất.

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

Biến đổi các danh sách

Trong các phiên bản cũ của thư viện Paging, việc chuyển đổi dữ liệu được phân trang sẽ dựa trên các phương thức sau:

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

Trong Paging 3, tất cả các phép biến đổi được áp dụng làm toán tử trên PagingData. Nếu bạn sử dụng bất kỳ phương thức nào trong danh sách trước đó để biến đổi danh sách được phân trang, bạn phải chuyển logic biến đổi của mình từ DataSource vào PagingData khi tạo Pager bằng PagingSource.

Để tìm hiểu thêm về cách biến đổi dữ liệu được phân trang bằng Paging 3, hãy xem bài viết Biến đổi các luồng dữ liệu.

PagedList

Phần này mô tả tất cả các thay đổi cần thiết để di chuyển quá trình triển khai Paging cũ để sử dụng PagerPagingData trong Paging 3.

Các lớp PagedListBuilder

PagingData thay thế PagedList hiện có khỏi Phân trang 2. Để di chuyển sang PagingData, bạn phải cập nhật các thông tin sau:

  • Cấu hình Paging được di chuyển từ PagedList.Config sang PagingConfig.
  • LivePagedListBuilderRxPagedListBuilder đã được kết hợp thành một lớp Pager duy nhất.
  • Pager hiển thị Flow<PagingData> có thể quan sát bằng thuộc tính .flow. Các biến thể RxJava và LiveData cũng có sẵn dưới dạng thuộc tính tiện ích. Các thuộc tính này có thể gọi từ Java thông qua các phương thức tĩnh và được cung cấp lần lượt từ các mô-đun paging-rxjava*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);

Để tìm hiểu thêm về cách thiết lập một luồng phản hồi gồm các đối tượng PagingData bằng Paging 3, hãy xem bài viết Thiết lập luồng PagingData.

BoundaryCallback cho các nguồn được phân lớp

Trong Paging 3, RemoteMediator sẽ thay thế PagedList.BoundaryCallback làm trình xử lý để phân trang dữ liệu từ mạng và cơ sở dữ liệu.

Để tìm hiểu thêm về cách sử dụng RemoteMediator để phân trang dữ liệu từ mạng và cơ sở dữ liệu trong Paging 3, hãy xem bài viết Lớp học lập trình Android Paging.

PagedListAdapter

Phần này mô tả tất cả các thay đổi cần thiết để di chuyển quá trình triển khai Paging cũ để sử dụng các lớp PagingDataAdapter hoặc AsyncPagingDataDiffer tại Paging 3.

Paging 3 cung cấp PagingDataAdapter để xử lý các luồng phản ứng PagingData mới. Nếu không, PagedListAdapterPagingDataAdapter sẽ có cùng một giao diện. Để di chuyển từ PagedListAdapter sang PagingDataAdapter, hãy thay đổi cách triển khai PagedListAdapter nhằm kéo dài PagingDataAdapter.

Để tìm hiểu thêm về PagingDataAdapter, hãy xem bài viết Xác định bộ chuyển đổi RecyclerView.

AsyncPagedListDiffer

Nếu bạn đang sử dụng một phương thức triển khai RecyclerView.Adapter tuỳ chỉnh với AsyncPagedListDiffer, hãy di chuyển phương thức triển khai của bạn để sử dụng AsyncPagingDataDiffer được cung cấp trong Paging 3:

Kotlin

AsyncPagingDataDiffer(diffCallback, listUpdateCallback)

Java

new AsyncPagingDataDiffer(diffCallback, listUpdateCallback);

Java

new AsyncPagingDataDiffer(diffCallback, listUpdateCallback);

Tài nguyên khác

Để tìm hiểu thêm về thư viện Paging, hãy xem các tài nguyên khác sau đây:

Lớp học lập trình

Mẫu