RecyclerView एडॉप्टर डेटा अपडेट करना - सही तरीका
RecyclerView एडॉप्टर को कुशलतापूर्वक अपडेट करने के लिए दानेदार notifyItem… विधियों या ListAdapter + DiffUtil का उपयोग करें। notifyDataSetChanged() से बचें—यह एनिमेशन को अक्षम करता है और पूरी सूची को रीबाइंड करता है।
सेटअप (निर्भरताएं)
dependencies {
implementation "androidx.recyclerview:recyclerview:1.3.2"
}
दृष्टिकोण 1 - ListAdapter + DiffUtil (अनुशंसित)
public class UserAdapter extends ListAdapter{ public UserAdapter() { super(DIFF_CALLBACK); } private static final DiffUtil.ItemCallback DIFF_CALLBACK = new DiffUtil.ItemCallback () { @Override public boolean areItemsTheSame(@NonNull User old, @NonNull User nw) { return old.id == nw.id; } @Override public boolean areContentsTheSame(@NonNull User old, @NonNull User nw) { return old.name.equals(nw.name) && old.email.equals(nw.email); } }; @NonNull @Override public VH onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { View v = LayoutInflater.from(parent.getContext()) .inflate(R.layout.item_user, parent, false); return new VH(v); } @Override public void onBindViewHolder(@NonNull VH holder, int position) { holder.bind(getItem(position)); } static class VH extends RecyclerView.ViewHolder { TextView name, email; VH(View v) { super(v); name = v.findViewById(R.id.tvName); email = v.findViewById(R.id.tvEmail); } void bind(User u) { name.setText(u.name); email.setText(u.email); } } }
गतिविधि में उपयोग
UserAdapter adapter = new UserAdapter(); recyclerView.setAdapter(adapter); // बाद में, नई सूची के साथ (उदाहरण: नेटवर्क प्रतिक्रिया से) adapter.submitList(newList); // DiffUtil स्वचालित रूप से न्यूनतम अपडिट्स की गणना करता है
दृष्टिकोण 2 - मैन्युअल दानेदार सूचनाएं (यदि ListAdapter का उपयोग नहीं कर रहे हैं)
public class SimpleAdapter extends RecyclerView.Adapter{ private final List data = new ArrayList<>(); // जोड़ें public void addItem(String item) { data.add(item); notifyItemInserted(data.size() - 1); } // हटाएं public void removeItem(int position) { data.remove(position); notifyItemRemoved(position); } // अपडेट करें public void updateItem(int position, String newValue) { data.set(position, newValue); notifyItemChanged(position); } // बल्क रिप्लेस public void setData(List newData) { data.clear(); data.addAll(newData); notifyDataSetChanged(); // बल्क रिप्लेस के लिए ठीक है } // ... VH, onCreate, onBind, getItemCount मानक }
तुलना
| विधि | पक्ष | विपक्ष |
|---|---|---|
| ListAdapter + DiffUtil | स्वचालित एनिमेशन, थ्रेड-सेफ, कम बॉयलरप्लेट | मॉडल में स्थिर ID की आवश्यकता |
| मैन्युअल notifyItem* | पूर्ण नियंत्रण, सरल मॉडल | त्रुटि-प्रवण, मैन्युअल इंडेक्स गणित |
| notifyDataSetChanged() | सरल | कोई एनिमेशन नहीं, पूरी सूची रीबाइंड, जैंक |
सामान्य गलतियां
- नई सूची ऑब्जेक्ट बनाना लेकिन एडॉप्टर को सूचित नहीं करना — हमेशा
submitList()याnotify…कॉल करें। - पृष्ठभूमि थ्रेड पर सूची को संशोधित करना — UI थ्रेड पर करें या
submitList()का उपयोग करें (आंतरिक रूप से पृष्ठभूमि डिफ की गणना करता है)। - पेलोड के साथ
notifyItemChanged(pos)का उपयोग न करना — आंशिक अपडेट के लिएnotifyItemChanged(pos, payload)पास करें।
परीक्षण युक्तियाँ
recyclerView.setItemAnimator(null)के साथ एनिमेशन अक्षम करें ताकि लॉजिक सत्यापित हो सके।- LayoutInspector का उपयोग करके पुष्टि करें कि केवल बदले हुए व्यू रीबाइंड होते हैं।
- बड़े डेटासेट (10k+) के साथ परीक्षण करें — DiffUtil बैकग्राउंड थ्रेड पर चलता है।
मूल उदाहरण की समीक्षा
मूल कोड notifyDataSetChanged() का उपयोग करता था एकल आइटम जोड़ के बाद—यह काम करता है लेकिन एनिमेशन खो देता है और O(n) रीबाइंड करता है। ऊपर दिए गए पैटर्न आधुनिक, एनिमेटेड और स्केलेबल हैं।