10

Với ListView chúng tôi đã có một mô hình tự nhiên tốt để lập bản đồ số dữ liệu từ db để liệt kê:Làm thế nào để sử dụng ContentObserver với RecyclerView?

DB ->ContentProvider ->CursorLoader ->CursorAdapter ->ListView

Cách tiếp cận này là tốt về lớp dữ liệu tách, hiệu suất và cập nhật dữ liệu tự động. Nhưng mẫu này không thực sự phù hợp với RecyclerView mới. Có một số phương pháp tiếp cận để bắt chước hành vi cũ:

Using the recyclerview with a database

Nhưng có một vấn đề với việc sử dụng cũ theo phong cách notifyDataSetChanged với RecyclerView. Nó không thể sử dụng các tính năng ItemAnimator, nó mất vị trí cuộn và nó không hiệu quả.

Vì vậy, làm thế nào chúng ta có thể hưởng lợi từ thông báo thay đổi finegraned khi sử dụng DB bọc trong ContentProvider? Cursor là tĩnh, và để có được dữ liệu mới từ nó, chúng ta cần phải nhận mới Cursor. Vì vậy, có vẻ như chúng ta sẽ cần một lớp dữ liệu tùy chỉnh trung gian, mà sẽ kết hợp dữ liệu từ Cursors và vạch trần List của đơn vị để RecyclerView.Adapter. Ngoài ra, chúng tôi sẽ phải tự lập bản đồ ContentObserveronChange() sự kiện để RecyclerView thông báo. Điều này cũng có nghĩa là chúng ta sẽ phải loại bỏ CursorLoader. Đó là một số lượng đáng kinh ngạc của công việc cho nhiệm vụ cơ bản như vậy.

Có giải pháp nào tốt hơn?

Trả lời

0

Bạn có thể sử dụng lớp DiffUtils để tính toán sự khác biệt giữa con trỏ cũ và mới.

Khi sử dụng nó, bạn chỉ cần thực hiện hai phương pháp:

  • areItemsTheSame() biết nếu hai mục đại diện cho mục logic tương tự (thậm chí nếu nội dung khác nhau). Thông thường, bạn sẽ căn cứ vào câu trả lời trên một lĩnh vực xác định mục của bạn;
  • areContentsTheSame() để biết hai mục có đại diện cho cùng một mục lôgic có nội dung chưa sửa đổi hay không.

Khi chênh lệch được tính toán, bạn có thể sau đó chỉ cần áp dụng nó vào bộ chuyển đổi của bạn và nó sẽ tự động gọi notifyItemChanged(), notifyItemInserted() hoặc notifyItemRemoved() accodingly.

Các vấn đề liên quan