Di chuyển sang Paging 3 (Khung hiển thị)

Các khái niệm và cách triển khai Jetpack Compose

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 của bạn đang sử dụng một 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 di chuyển sang Paging 3.

Nếu Paging 3 là phiên bản đầu tiên của thư viện Paging mà bạn đang 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 của 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.

Tổng quan về quá trình di chuyển

Để di chuyển hoàn toàn sang Paging 3 trong khi vẫn giữ nguyên quá trình triển khai RecyclerView, bạn phải cập nhật các thành phần sau:

Thành phần Paging 2

Thay thế Paging 3

PageKeyedDataSource

PagingSource

PagedListAdapter

PagingDataAdapter

LivePagedListBuilder

Pager

BoundaryCallback

RemoteMediator

Các lớp DataSource

Phần này mô tả những 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úp 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ũ thường 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.

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

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 .flow tài sản. 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.

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

Để 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.

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.

Phân trang 2 sử dụng PagedListAdapter để liên kết PagedList với RecyclerView. Trong Paging 3, PagingData thay thế PagedList.

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 (RxJava)

new AsyncPagingDataDiffer(diffCallback, listUpdateCallback);

Java (Guava/LiveData)

new AsyncPagingDataDiffer(diffCallback, listUpdateCallback);