वेन हम उस setHasFixedSize(true)
पर सेट RecyclerView
करते हैं इसका मतलब है कि पुनर्नवीनीकरण का आकार तय हो गया है और एडेप्टर सामग्री से प्रभावित नहीं है। और इस मामले onLayout
में रिसाइकलर पर नहीं बुलाया जाता है जब हम एडेप्टर के डेटा को अपडेट करते हैं (लेकिन एक अपवाद है)।
आइए उदाहरण के लिए चलते हैं:
RecyclerView
एक है RecyclerViewDataObserver
( इस फ़ाइल में खोजने डिफ़ॉल्ट implemntation कई तरीके के साथ), मुख्य रूप से महत्वपूर्ण है:
void triggerUpdateProcessor() {
if (POST_UPDATES_ON_ANIMATION && mHasFixedSize && mIsAttached) {
ViewCompat.postOnAnimation(RecyclerView.this, mUpdateChildViewsRunnable);
} else {
mAdapterUpdateDuringMeasure = true;
requestLayout();
}
}
अगर हम सेट इस विधि कहा जाता है setHasFixedSize(true)
के माध्यम से और एक एडाप्टर के डेटा को अद्यतन: notifyItemRangeChanged, notifyItemRangeInserted, notifyItemRangeRemoved or notifyItemRangeMoved
। इस मामले में रिसाइकलर के लिए कोई कॉल नहीं है onLayout
, लेकिन requestLayout
चिल्ड को अपडेट करने के लिए कॉल है ।
लेकिन अगर हम setHasFixedSize(true)
एक एडॉप्टर के डेटा को सेट और अपडेट करते हैं, notifyItemChanged
तो onChange
रिसाइकलर के डिफॉल्ट में RecyclerViewDataObserver
कॉल होता है और कोई कॉल नहीं होता है triggerUpdateProcessor
। इस मामले में recycler onLayout
कहा जाता है जब भी हम सेट setHasFixedSize
true
या false
।
// no calls to triggerUpdateProcessor
@Override
public void onChanged() {
assertNotInLayoutOrScroll(null);
mState.mStructureChanged = true;
processDataSetCompletelyChanged(true);
if (!mAdapterHelper.hasPendingUpdates()) {
requestLayout();
}
}
// calls to triggerUpdateProcessor
@Override
public void onItemRangeChanged(int positionStart, int itemCount, Object payload) {
assertNotInLayoutOrScroll(null);
if (mAdapterHelper.onItemRangeChanged(positionStart, itemCount, payload)) {
triggerUpdateProcessor();
}
}
अपने आप से कैसे जांचें:
कस्टम बनाएँ RecyclerView
और ओवरराइड करें:
override fun requestLayout() {
Log.d("CustomRecycler", "requestLayout is called")
super.requestLayout()
}
override fun invalidate() {
Log.d("CustomRecycler", "invalidate is called")
super.invalidate()
}
override fun onLayout(changed: Boolean, l: Int, t: Int, r: Int, b: Int) {
Log.d("CustomRecycler", "onLayout is called")
super.onLayout(changed, l, t, r, b)
}
match_parent
(Xml में) पुनर्नवीनीकरण आकार सेट करें । एडेप्टर के डेटा का उपयोग करके replaceData
और सेट करने के replaceOne
साथ setHasFixedSize(true)
और फिर अपडेट करने का प्रयास करें false
।
// onLayout is called every time
fun replaceAll(data: List<String>) {
dataSet.clear()
dataSet.addAll(data)
this.notifyDataSetChanged()
}
// onLayout is called only for setHasFixedSize(false)
fun replaceOne(data: List<String>) {
dataSet.removeAt(0)
dataSet.addAll(0, data[0])
this.notifyItemChanged(0)
}
और अपना लॉग चेक करें।
मेरा लॉग:
// for replaceAll
D/CustomRecycler: requestLayout is called
D/CustomRecycler: onMeasure is called
D/CustomRecycler: onMeasure is called
D/CustomRecycler: onLayout
D/CustomRecycler: requestLayout is called
D/CustomRecycler: requestLayout is called
D/CustomRecycler: onDraw is called
// for replaceOne
D/CustomRecycler: requestLayout is called
D/CustomRecycler: onDraw is called
D/CustomRecycler: requestLayout is called
D/CustomRecycler: onDraw is called
संक्षेप:
यदि हम setHasFixedSize(true)
कॉल करने के अलावा किसी अन्य तरीके से पर्यवेक्षक को सूचित करने के साथ एडॉप्टर के डेटा को सेट और अपडेट करते हैं notifyDataSetChanged
, तो आपके पास कुछ पूर्णता है, क्योंकि रिसाइकलर onLayout
विधि के लिए कोई कॉल नहीं है ।