Hướng dẫn này dựa trên tổng quan về Thư viện Paging, mô tả cách bạn có thể trình bày danh sách thông tin cho người dùng trong giao diện người dùng của ứng dụng, đặc biệt là khi thông tin này thay đổi.
Kết nối UI (giao diện người dùng) với mô hình chế độ xem
Bạn có thể kết nối một bản sao của LiveData<PagedList>
với một PagedListAdapter
, như minh hoạ trong đoạn mã sau:
Kotlin
class ConcertActivity : AppCompatActivity() { private val adapter = ConcertAdapter() // Use the 'by viewModels()' Kotlin property delegate // from the activity-ktx artifact private val viewModel: ConcertViewModel by viewModels() override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState); viewModel.concerts.observe(this, Observer { adapter.submitList(it) }) } }
Java
public class ConcertActivity extends AppCompatActivity { private ConcertAdapter adapter = new ConcertAdapter(); private ConcertViewModel viewModel; @Override public void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); viewModel = new ViewModelProvider(this).get(ConcertViewModel.class); viewModel.concertList.observe(this, adapter::submitList); } }
Khi nguồn dữ liệu cung cấp các bản sao mới của PagedList
, activity sẽ gửi các đối tượng này đến bộ chuyển đổi. Hoạt động triển khai PagedListAdapter
xác định cách tính toán các bản cập nhật và tự động xử lý sự khác biệt giữa phân trang và danh sách. Do đó, ViewHolder
chỉ cần ràng buộc với một mục cụ thể đã cung cấp:
Kotlin
class ConcertAdapter() : PagedListAdapter<Concert, ConcertViewHolder>(DIFF_CALLBACK) { override fun onBindViewHolder(holder: ConcertViewHolder, position: Int) { val concert: Concert? = getItem(position) // Note that "concert" is a placeholder if it's null. holder.bindTo(concert) } companion object { private val DIFF_CALLBACK = ... // See Implement the diffing callback section. } }
Java
public class ConcertAdapter extends PagedListAdapter<Concert, ConcertViewHolder> { protected ConcertAdapter() { super(DIFF_CALLBACK); } @Override public void onBindViewHolder(@NonNull ConcertViewHolder holder, int position) { Concert concert = getItem(position); // Note that "concert" can be null if it's a placeholder. holder.bindTo(concert); } private static DiffUtil.ItemCallback<Concert> DIFF_CALLBACK = ... // See Implement the diffing callback section. }
PagedListAdapter
sẽ xử lý các sự kiện tải trang bằng cách dùng đối tượng PagedList.Callback
. Khi người dùng cuộn, PagedListAdapter
sẽ gọi PagedList.loadAround()
để cung cấp gợi ý cho PagedList
cơ bản về những mục cần tìm nạp trong DataSource
.
Triển khai lệnh gọi lại so sánh
Mẫu sau đây minh hoạ cách triển khai thủ công của areContentsTheSame()
, trong đó so sánh các trường đối tượng có liên quan:
Kotlin
private val DIFF_CALLBACK = object : DiffUtil.ItemCallback<Concert>() { // The ID property identifies when items are the same. override fun areItemsTheSame(oldItem: Concert, newItem: Concert) = oldItem.id == newItem.id // If you use the "==" operator, make sure that the object implements // .equals(). Alternatively, write custom data comparison logic here. override fun areContentsTheSame( oldItem: Concert, newItem: Concert) = oldItem == newItem }
Java
private static DiffUtil.ItemCallback<Concert> DIFF_CALLBACK = new DiffUtil.ItemCallback<Concert>() { @Override public boolean areItemsTheSame(Concert oldItem, Concert newItem) { // The ID property identifies when items are the same. return oldItem.getId() == newItem.getId(); } @Override public boolean areContentsTheSame(Concert oldItem, Concert newItem) { // Don't use the "==" operator here. Either implement and use .equals(), // or write custom data comparison logic here. return oldItem.equals(newItem); } };
Vì bộ chuyển đổi của bạn bao gồm định nghĩa về việc so sánh các mục, nên bộ chuyển đổi sẽ tự động phát hiện các thay đổi đối với các mục này khi đối tượng PagedList
mới được tải. Do đó, bộ chuyển đổi sẽ kích hoạt các hiệu ứng tải mục hiệu quả trong đối tượng RecyclerView
.
So sánh bằng loại bộ chuyển đổi khác
Nếu bạn không kế thừa từ PagedListAdapter
— chẳng hạn như bạn dùng thư viện cung cấp bộ chuyển đổi riêng — bạn vẫn có thể dùng chức năng khác biệt của bộ chuyển đổi thư viện Paging bằng cách trực tiếp xử lý đối tượng AsyncPagedListDiffer
.
Cung cấp phần giữ chỗ trong UI (giao diện người dùng)
Trong trường hợp bạn muốn UI (giao diện người dùng) hiện một danh sách trước khi ứng dụng hoàn tất quá trình tìm nạp dữ liệu, bạn có thể hiện các mục danh sách trong phần giữ chỗ cho người dùng. PagedList
xử lý trường hợp này bằng cách trình bày dữ liệu mục danh sách dưới dạng null
cho đến khi dữ liệu được tải.
Phần giữ chỗ có những lợi ích sau:
- Hỗ trợ thanh cuộn:
PagedList
cung cấp số lượng mục trong danh sách choPagedListAdapter
. Thông tin này cho phép bộ chuyển đổi vẽ một thanh cuộn để truyền tải kích thước đầy đủ của danh sách. Khi tải các trang mới, thanh cuộn sẽ không nhảy vì danh sách của bạn không thay đổi kích thước. - Không cần vòng quay đang tải: Vì kích thước danh sách đã được xác định, nên bạn không cần cảnh báo người dùng rằng nhiều mục khác đang tải. Phần giữ chỗ sẽ tự truyền tải thông tin đó.
Trước khi thêm khả năng hỗ trợ cho phần giữ chỗ, hãy lưu ý những điều kiện tiên quyết sau đây:
- Yêu cầu tập dữ liệu có thể đếm được: Các bản sao của
DataSource
trong thư viện lưu trữ Room có thể đếm các mục một cách hiệu quả. Tuy nhiên, nếu bạn đang sử dụng giải pháp lưu trữ cục bộ tuỳ chỉnh hoặc cấu trúc dữ liệu chỉ dành cho mạng, thì bạn có thể tốn kém hoặc thậm chí không thể xác định có bao nhiêu mục bao gồm tập dữ liệu của bạn. - Yêu cầu bộ chuyển đổi tính đến các mục chưa tải: Bộ chuyển đổi hoặc cơ chế trình bày mà bạn dùng để chuẩn bị danh sách cho lạm phát cần phải xử lý các mục trong danh sách rỗng. Ví dụ: khi ràng buộc dữ liệu với
ViewHolder
, bạn cần cung cấp các giá trị mặc định để đại diện cho dữ liệu chưa tải. - Yêu cầu chế độ xem mục có cùng kích thước: Nếu kích thước mục trong danh sách có thể thay đổi theo nội dung của các mục đó, chẳng hạn như nội dung cập nhật trên mạng xã hội, thì việc phân chia giữa các mục sẽ không ổn. Chúng tôi thực sự khuyên bạn nên vô hiệu hoá phần giữ chỗ trong trường hợp này.
Gửi ý kiến phản hồi
Hãy chia sẻ phản hồi và ý kiến của bạn với chúng tôi thông qua các tài nguyên sau:
- Công cụ theo dõi lỗi
- Báo cáo sự cố để chúng tôi có thể sửa lỗi.
Tài nguyên khác
Để tìm hiểu thêm về Thư viện Paging, hãy tham khảo các tài nguyên sau.
Mẫu
Lớp học lập trình
Video
- Android Jetpack: quản lý danh sách vô hạn bằng RecyclerView và Paging (Google I/O '18)
- Android Jetpack: Paging
Đề 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ổng quan về thư viện Paging 2
- Di chuyển sang Paging 3
- Thu thập dữ liệu được phân trang