Wen เราตั้งsetHasFixedSize(true)อยู่บนRecyclerViewหมายถึงว่าขนาดของรีไซเคิลได้รับการแก้ไขและไม่ได้รับผลกระทบจากเนื้อหาอะแดปเตอร์ และในกรณีนี้onLayoutจะไม่ถูกเรียกใช้กับผู้รีไซเคิลเมื่อเราอัปเดตข้อมูลของอะแดปเตอร์ (แต่มีข้อยกเว้น)
ไปที่ตัวอย่าง:
RecyclerViewมีRecyclerViewDataObserver( ค้นหาการปรับใช้เริ่มต้นในไฟล์นี้ ) ด้วยวิธีการต่างๆที่สำคัญคือ:
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ในกรณีนี้รีไซเคิลonLayoutเรียกว่าเมื่อใดก็ตามที่เราตั้งหรือsetHasFixedSize truefalse
@Override
public void onChanged() {
    assertNotInLayoutOrScroll(null);
     mState.mStructureChanged = true;
     processDataSetCompletelyChanged(true);
     if (!mAdapterHelper.hasPendingUpdates()) {
         requestLayout();
     }
}
@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  มี seting แล้วsetHasFixedSize(true)false
fun replaceAll(data: List<String>) {
    dataSet.clear()
    dataSet.addAll(data)
    this.notifyDataSetChanged()
}
fun replaceOne(data: List<String>) {
    dataSet.removeAt(0)
    dataSet.addAll(0, data[0])
    this.notifyItemChanged(0)
}
และตรวจสอบบันทึกของคุณ
บันทึกของฉัน:
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
D/CustomRecycler: requestLayout is called
D/CustomRecycler: onDraw is called
D/CustomRecycler: requestLayout is called
D/CustomRecycler: onDraw is called
สรุป:
หากเราตั้งค่าsetHasFixedSize(true)และอัปเดตข้อมูลของอแด็ปเตอร์โดยแจ้งผู้สังเกตการณ์ด้วยวิธีอื่นที่ไม่ใช่การโทรแสดงnotifyDataSetChangedว่าคุณมีประสิทธิภาพเนื่องจากไม่มีการเรียกใช้onLayoutเมธอดรีไซเคิล