Tổng quan về thư viện Paging   Một phần của Android Jetpack.

Thư viện Paging giúp bạn tải và hiển thị các trang dữ liệu của một tập dữ liệu lớn hơn từ bộ nhớ cục bộ hoặc qua mạng. Phương pháp này cho phép ứng dụng sử dụng cả băng thông mạng và tài nguyên hệ thống một cách hiệu quả hơn. Các thành phần của thư viện Paging được thiết kế để phù hợp với cấu trúc ứng dụng Android được đề xuất, tích hợp mượt mà với các thành phần khác của Jetpack và cung cấp khả năng hỗ trợ Kotlin hàng đầu.

Lợi ích của việc sử dụng thư viện Paging

Thư viện Paging bao gồm các tính năng sau:

  • Tính năng lưu dữ liệu được phân trang vào bộ nhớ đệm trong bộ nhớ. Tính năng này giúp đảm bảo rằng ứng dụng dùng tài nguyên hệ thống một cách hiệu quả trong khi làm việc với dữ liệu được phân trang.
  • Tính năng loại bỏ yêu cầu trùng lặp tích hợp sẵn giúp đảm bảo ứng dụng dùng băng thông mạng và tài nguyên hệ thống một cách hiệu quả.
  • Khả năng hỗ trợ hàng đầu cho các coroutine và luồng Kotlin.
  • Tính năng hỗ trợ được tích hợp sẵn để xử lý lỗi, bao gồm khả năng làm mới và thử lại.

Thiết lập

Để nhập các thành phần Paging vào ứng dụng Android, hãy thêm các phần phụ thuộc sau vào tệp build.gradle của ứng dụng:

Kotlin

dependencies {
  val paging_version = "3.4.2"

  implementation("androidx.paging:paging-common:$paging_version")

  // Jetpack Compose integration
  implementation("androidx.paging:paging-compose:$paging_version")
}

Groovy

dependencies {
  def paging_version = "3.4.2"

  implementation "androidx.paging:paging-common:$paging_version"

  // Jetpack Compose integration
  implementation "androidx.paging:paging-compose:$paging_version"
}

Cấu trúc thư viện

Các thành phần của thư viện Paging hoạt động trong 3 lớp của ứng dụng:

  • Lớp lưu trữ
  • Lớp ViewModel
  • Lớp giao diện người dùng
Hình ảnh cho thấy luồng dữ liệu được phân trang di chuyển từ các thành phần PagingSource hoặc RemoteMediator trong lớp lưu trữ đến thành phần Pager trong lớp ViewModel.
    Sau đó, thành phần Pager sẽ hiển thị một Luồng PagingData cho các thành phần bố cục lười biếng trong lớp giao diện người dùng.
Hình 1. Một ví dụ về cách thư viện Paging nằm vừa vặn trong cấu trúc ứng dụng.

Phần này mô tả các thành phần thư viện Paging hoạt động ở mỗi lớp và cách các thành phần này hoạt động cùng nhau để tải và hiển thị dữ liệu được phân trang.

Lớp kho lưu trữ

Thành phần thư viện Paging chính trong lớp lưu trữ là PagingSource. Mỗi đối tượng PagingSource xác định một nguồn dữ liệu và cách truy xuất dữ liệu từ nguồn đó. Đối tượng PagingSource có thể tải dữ liệu từ bất kỳ nguồn nào, bao gồm cả nguồn trên mạng và cơ sở dữ liệu cục bộ.

Một thành phần khác trong thư viện Paging mà bạn có thể sử dụng là RemoteMediator. Đối tượng RemoteMediator xử lý phân trang từ một nguồn dữ liệu phân lớp, chẳng hạn như nguồn dữ liệu trên mạng có bộ nhớ đệm cơ sở dữ liệu cục bộ.

Lớp ViewModel

Thành phần Pager cung cấp API công khai để tạo các thực thể của PagingData được hiển thị trong các luồng phản ứng, dựa trên đối tượng PagingSource và đối tượng cấu hình PagingConfig.

Thành phần kết nối lớp ViewModel với giao diện người dùng là PagingData. Đối tượng PagingData là một vùng chứa ảnh chụp nhanh của dữ liệu được phân trang. Phương thức này truy vấn một đối tượng PagingSource và lưu trữ kết quả đó.

Lớp giao diện người dùng

API giao diện người dùng Paging chính là collectAsLazyPagingItems(). Thư viện này hiển thị các mục được phân trang dưới dạng danh sách dữ liệu mà các thành phần bố cục lười biếng của Compose (chẳng hạn như LazyColumnLazyRow) có thể dễ dàng sử dụng.

Thêm thư viện androidx.paging:paging-compose để sử dụng các API tương thích với Compose. Các API này cho phép giao diện người dùng tự động phản ứng với các lần tải, cập nhật và lỗi dữ liệu mà không cần bộ chuyển đổi hoặc logic so sánh. Sử dụng hàm mở rộng collectAsLazyPagingItems() trên Flow<PagingData> để truyền LazyPagingItems đã trả về đến items() trong LazyColumn.

@Composable
fun MessageList(pager: Pager<Int, Message>) {
    val lazyPagingItems = pager.flow.collectAsLazyPagingItems()

    LazyColumn {
        items(
            lazyPagingItems.itemCount,
            key = lazyPagingItems.itemKey { it.id }
        ) { index ->
            val message = lazyPagingItems[index]
            if (message != null) {
                MessageRow(message)
            } else {
                MessagePlaceholder()
            }
        }
    }
}

Để biết thêm thông tin, hãy xem bài viết Các tập dữ liệu lớn (phân trang).