Tìm hiểu về DiffUtil và ListAdapter

Tram Ho

1. Giới thiệu về DiffUtil

RecyclerView là một ViewGroup được giới thiệu trong Android L (Android API 21) được hỗ trợ trong support-v7 version. Với rất nhiều tính năng mới mạnh mẽ hơn người tiền nhiệm ListView. Một tính năng nổi bật trong đó là Notify data không chỉ có duy nhất notifyDataSetChanged() mà còn có thêm như notifyItemChange()notifyItemMoved()notifyItemInserted() rất tiện lợi cho ta việc xử lý khi có thay đổi ở đâu đó trên list.

Nhưng trong một số trường hợp bạn có danh sách lớn, mà thực hiện nhiều thao tác phức tạp trên đó không dễ gì để biết phần tử nào cần thông báo cho RecyclerView biết mà cập nhật hiển thị cho đúng , lúc đó nếu gọi notifyDataSetChanged() để cho biết toàn bộ dữ liệu đã đổi thì hiệu suất hoạt động của ứng dụng thấp làm giảm trải nghiệm người dùng. Nhưng đừng lo có một lớp tiện ích tên là DiffUtil sẽ giúp chúng ta làm việc đó.

Đến bản 24.2.0, RecyclerView support library, v7 package cung cấp class được gọi là DiffUtil. Về cơ bản nó tìm điểm khác nhau giữa 2 list và cung cấp output là list cập nhật, nó được sử dụng để thông báo cập nhật cho một adapter của RecyclerView. Về cơ bản DiffUtil vẫn sử dụng các method của RecyclerView.Adapter để thông báo cho adapter cập nhật dư liệu như

  • notifyItemChange()
  • notifyItemMoved()
  • notifyItemInserted()

Và sử dụng thuật toán của Eugene W. Myers để tính số cập nhật tối thiểu

Triển khai DiffUtil

Các hàm cần lưu ý

  • getOldListSize() : Nó trả về kích thước của danh sách cũ.
  • getNewListSize() : Trả về kích thước của danh sách mới.
  • areItemsTheSame(int oldItemPosition, int newItemPosition) : Kiểm tra xem các mục riêng lẻ của danh sách có giống nhau không. Điều này có thể được thực hiện thông qua việc kiểm tra id chúng
  • areContentsTheSame(int oldItemPosition, int newItemPosition) : Kiểm tra xem nội dung của dữ liệu danh sách có giống nhau không. Phương thức này được gọi bởi DiffUtil chỉ khi areItemsTheSametrả về true.
  • getChangePayload(int oldItemPosition, int newItemPosition) : Nếu areItemTheSame trả về true và areContentsTheSame trả về false, DiffUtil gọi phương thức này để trả về sự thay đổi

UserDiffUtil.class

Và triển khai trong Adapter

UserAdapter.class

.u2b31c2b411337ed25f0ef29d73c7718a { padding:0px; margin: 0; padding-top:1em!important; padding-bottom:1em!important; width:100%; display: block; font-weight:bold; background-color:#eaeaea; border:0!important; border-left:4px solid #34495E!important; text-decoration:none; } .u2b31c2b411337ed25f0ef29d73c7718a:active, .u2b31c2b411337ed25f0ef29d73c7718a:hover { opacity: 1; transition: opacity 250ms; webkit-transition: opacity 250ms; text-decoration:none; } .u2b31c2b411337ed25f0ef29d73c7718a { transition: background-color 250ms; webkit-transition: background-color 250ms; opacity: 1; transition: opacity 250ms; webkit-transition: opacity 250ms; } .u2b31c2b411337ed25f0ef29d73c7718a .ctaText { font-weight:bold; color:inherit; text-decoration:none; font-size: 16px; } .u2b31c2b411337ed25f0ef29d73c7718a .postTitle { color:#000000; text-decoration: underline!important; font-size: 16px; } .u2b31c2b411337ed25f0ef29d73c7718a:hover .postTitle { text-decoration: underline!important; }

  Multi-Thread và Service trong Android

.ud9dc24bae3c60498835d44848734ee7c { padding:0px; margin: 0; padding-top:1em!important; padding-bottom:1em!important; width:100%; display: block; font-weight:bold; background-color:#eaeaea; border:0!important; border-left:4px solid #34495E!important; text-decoration:none; } .ud9dc24bae3c60498835d44848734ee7c:active, .ud9dc24bae3c60498835d44848734ee7c:hover { opacity: 1; transition: opacity 250ms; webkit-transition: opacity 250ms; text-decoration:none; } .ud9dc24bae3c60498835d44848734ee7c { transition: background-color 250ms; webkit-transition: background-color 250ms; opacity: 1; transition: opacity 250ms; webkit-transition: opacity 250ms; } .ud9dc24bae3c60498835d44848734ee7c .ctaText { font-weight:bold; color:inherit; text-decoration:none; font-size: 16px; } .ud9dc24bae3c60498835d44848734ee7c .postTitle { color:#000000; text-decoration: underline!important; font-size: 16px; } .ud9dc24bae3c60498835d44848734ee7c:hover .postTitle { text-decoration: underline!important; }

  Cơ bản về Android App Bundle

2. Giới thiệu về ListAdapter

Từ những hiệu quả mà DiffUtil mang lại thì trong support library 27.1.0 ListAdapter ra đời nó là 1 Wraper của RecyclerView.Adapter giúp cho đơn giản hóa code cần thiết để làm việc với RecyclerView và có thể tự động lưu trữ list Item cũ và sử dụng DiffUtil để chỉ update những items có sự thay đổi.

Nào cũng xem thử cách code bình thường chúng ta thường hay làm

Cách sử dụng Adapter cũ

Còn đây là cách sử dụng Adapter mới

Bất cứ khi nào bạn cần update adapter, bạn có thể cung cấp một list item mới để nó sử dụng submitList(List) method.

3. Tổng kết

Trên đây là hướng dẫn cơ bản của mình về DiffUtil và ListAdapter về cơ bản thì nó khá giống cách triển khai RecyclerView.Adapter cũ ListAdapter như là cầu nối giữa chúng tạo nên sự linh hoạt cũng như hiệu năng khi các bạn xử lý những bài toán lớn khi có sự thay đổi.

Nguồn tham khảo:

https://www.journaldev.com/20873/android-recyclerview-diffutil?fbclid=IwAR3FzotH0rtTTSUkF386DmOhWI3Ds4VY7yVp6R6o8dCdAT1IVs7vC3eSiZw

https://medium.com/@trionkidnapper/recyclerview-more-animations-with-less-code-using-support-library-listadapter-62e65126acdb?fbclid=IwAR0-vTtj2naxa_sHrnEhRMFt1M-xDljVDSvTFo7xLl5KCFaqnXlEKU3_5PY

.u5a1dcd4a434e9366402f51d342b670fa { padding:0px; margin: 0; padding-top:1em!important; padding-bottom:1em!important; width:100%; display: block; font-weight:bold; background-color:#eaeaea; border:0!important; border-left:4px solid #34495E!important; text-decoration:none; } .u5a1dcd4a434e9366402f51d342b670fa:active, .u5a1dcd4a434e9366402f51d342b670fa:hover { opacity: 1; transition: opacity 250ms; webkit-transition: opacity 250ms; text-decoration:none; } .u5a1dcd4a434e9366402f51d342b670fa { transition: background-color 250ms; webkit-transition: background-color 250ms; opacity: 1; transition: opacity 250ms; webkit-transition: opacity 250ms; } .u5a1dcd4a434e9366402f51d342b670fa .ctaText { font-weight:bold; color:inherit; text-decoration:none; font-size: 16px; } .u5a1dcd4a434e9366402f51d342b670fa .postTitle { color:#000000; text-decoration: underline!important; font-size: 16px; } .u5a1dcd4a434e9366402f51d342b670fa:hover .postTitle { text-decoration: underline!important; }

  Giới thiệu công cụ VisBug, chính chủ Google làm ra giúp cuộc đời FrontEnd Designer của bạn bớt khổ cực

.u0eef7b6bbbdcd03a8ce705c9b7a4eec9 { padding:0px; margin: 0; padding-top:1em!important; padding-bottom:1em!important; width:100%; display: block; font-weight:bold; background-color:#eaeaea; border:0!important; border-left:4px solid #34495E!important; text-decoration:none; } .u0eef7b6bbbdcd03a8ce705c9b7a4eec9:active, .u0eef7b6bbbdcd03a8ce705c9b7a4eec9:hover { opacity: 1; transition: opacity 250ms; webkit-transition: opacity 250ms; text-decoration:none; } .u0eef7b6bbbdcd03a8ce705c9b7a4eec9 { transition: background-color 250ms; webkit-transition: background-color 250ms; opacity: 1; transition: opacity 250ms; webkit-transition: opacity 250ms; } .u0eef7b6bbbdcd03a8ce705c9b7a4eec9 .ctaText { font-weight:bold; color:inherit; text-decoration:none; font-size: 16px; } .u0eef7b6bbbdcd03a8ce705c9b7a4eec9 .postTitle { color:#000000; text-decoration: underline!important; font-size: 16px; } .u0eef7b6bbbdcd03a8ce705c9b7a4eec9:hover .postTitle { text-decoration: underline!important; }

  Giới thiệu LevelDB và so sánh hiệu năng với MySQL

Chia sẻ bài viết ngay

Nguồn bài viết : viblo