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, khả năng hỗ trợ hàng đầu cho các coroutine Kotlin và Flow, cũng như khả năng tích hợp liền mạch với Jetpack Compose.
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à
FlowKotlin. - 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, cũng như các mục trạng thái tải cho danh sách tải từng phần.
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 những thành phần chính này từ Paging 2:
- Các lớp
DataSource PagedList- Lớp trình bày (đến
LazyPagingItems)
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 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 lựa chọn di chuyển sau:
- Bạn có thể di chuyển
DataSourcesangPagingSourcenhư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 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.
Mã PageKeyedDataSource, PositionalDataSource và ItemKeyedDataSource 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.
// Replaces ItemKeyedDataSource.
override fun getRefreshKey(state: PagingState<String, User>): String? {
return state.anchorPosition?.let { anchorPosition ->
state.getClosestItemToPosition(anchorPosition)?.id
}
}
// Replacing PositionalDataSource.
override fun getRefreshKey(state: PagingState<Int, User>): Int? {
return state.anchorPosition
}
Biến đổi các danh sách
Trong các phiên bản thấp hơn 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.mapDataSource.mapByPageDataSource.Factory.mapDataSource.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 Pager và PagingData 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.ConfigsangPagingConfig. - Các lớp trình tạo cũ đã được kết hợp thành một lớp
Pagerduy nhất. Pagerhiển thịFlow<PagingData>có thể quan sát bằng thuộc tính.flow.
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)
Để 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 Lớp học lập trình Android Paging.
LazyPagingItems
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 LazyPagingItems trong Paging 3.
Paging 3 cung cấp collectAsLazyPagingItems để xử lý luồng PagingData mới. Để di chuyển lớp trình bày, hãy dùng cấu phần phần mềm paging-compose và collectAsLazyPagingItems để thu thập các mục PagingData rồi hiển thị chúng trong các hàm @Composable.
Để tìm hiểu thêm về LazyPagingItems, hãy xem bài viết Tải và hiển thị dữ liệu được phân trang.
So sánh và cập nhật danh sách
Nếu bạn hiện đang sử dụng logic so sánh danh sách tuỳ chỉnh, hãy di chuyển phương thức triển khai của bạn để sử dụng LazyPagingItems được cung cấp trong Paging 3. Để đảm bảo quá trình so sánh diễn ra đúng cách, hãy chỉ định một khoá mục trên danh sách tải từng phần:
@Composable
fun UserScreen(viewModel: UserViewModel) {
// Collects the Flow into a LazyPagingItems object
val lazyPagingItems = viewModel.pager.flow.collectAsLazyPagingItems()
UserList(lazyPagingItems)
}
@Composable
fun UserScreen(viewModel: UserViewModel) {
val lazyPagingItems = viewModel.pager.flow.collectAsLazyPagingItems()
UserList(lazyPagingItems)
}
@Composable
fun UserList(lazyPagingItems: LazyPagingItems<User>) {
LazyColumn {
items(
count = lazyPagingItems.itemCount,
// Provide a stable key for each item, similar to DiffUtil in Views
key = lazyPagingItems.itemKey { user -> user.id }
) { index ->
val user = lazyPagingItems[index]
if (user != null) {
UserRow(user = user)
}
}
}
}
Để biết thêm thông tin về khoá mục, hãy xem phần Khoá mục.
Các trạng thái đang tải
Trong Phân trang 3, bạn không cần một bộ điều hợp riêng để hiển thị tiêu đề hoặc chân trang cho trạng thái tải. Đối tượng LazyPagingItems hiển thị một thuộc tính loadState mà bạn có thể kiểm tra trực tiếp trong LazyColumn.
LazyColumn {
// ... items(lazyPagingItems) go here ...
// Show loading spinner at bottom of list when appending data
if (lazyPagingItems.loadState.append is LoadState.Loading) {
item {
CircularProgressIndicator(modifier = Modifier.fillMaxWidth())
}
}
}
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:
Tài liệu
Xem nội dung
Đề xuất cho bạn
- Lưu ý: văn bản có đường liên kết sẽ hiện khi JavaScript tắt
- Tải và hiện dữ liệu được phân trang
- Thu thập dữ liệu được phân trang
- Phân trang qua mạng và cơ sở dữ liệu