تكرار السؤال: …
الإجابة المختصرة
يحسب DiffUtil الفروقات بين قائمتين في خلفية غير متزامنة ويطبق تحريكات دقيقة وموضعية للعناصر المتغيرة فقط بدلاً من إعادة رسم القائمة بأكملها.
الشرح
استدعاء notifyDataSetChanged يعيد بناء وتحديث كل عنصر مرئي على الشاشة ويلغي أنيميشن التمرير. يحسب DiffUtil أصغر تسلسل من عمليات التعديل (إضافة، حذف، تحريك، تعديل جزئي) باستخدام خوارزمية Eugene W. Myers. ويغلف ListAdapter هذا المنطق في كلاس جاهز يرسل القوائم الجديدة تلقائيًا عبر submitList على background thread.
مثال بالكود
class UserDiffCallback : DiffUtil.ItemCallback<User>() {
override fun areItemsTheSame(oldItem: User, newItem: User): Boolean = oldItem.id == newItem.id
override fun areContentsTheSame(oldItem: User, newItem: User): Boolean = oldItem == newItem
}
class UserListAdapter : ListAdapter<User, UserViewHolder>(UserDiffCallback()) { ... }
// التحديث السلس:
userListAdapter.submitList(newList)أخطاء شائعة
- تمرير نفس المرجع القابل للتعديل (MutableList) إلى submitList دون إنشاء قائمة جديدة، مما يمنع DiffUtil من اكتشاف أي تغيير.
- كتابة شروط خاطئة داخل areItemsTheSame تجعل الـ ID يتطابق مع عناصر مختلفة تمامًا.