นี่เป็นสถานการณ์ที่ยุ่งยากขออภัยที่เอกสารไม่เพียงพอ
เมื่อเนื้อหาของอะแด็ปเตอร์เปลี่ยน (และคุณเรียกใช้notify***()
) RecyclerView ร้องขอเค้าโครงใหม่ ตั้งแต่ช่วงเวลานั้นจนกระทั่งระบบโครงร่างตัดสินใจคำนวณโครงร่างใหม่ (<16 ms) ตำแหน่งโครงร่างและตำแหน่งอะแดปเตอร์อาจไม่ตรงกันเนื่องจากเค้าโครงยังไม่สะท้อนการเปลี่ยนแปลงอะแด็ปเตอร์
ในกรณีที่การใช้งานของคุณเนื่องจากข้อมูลของคุณที่เกี่ยวข้องกับเนื้อหาของอะแดปเตอร์ของคุณ (และผมถือว่าข้อมูลที่มีการเปลี่ยนแปลงในเวลาเดียวกันกับการเปลี่ยนแปลงอะแดปเตอร์), adapterPosition
คุณควรจะใช้
อย่างไรก็ตามโปรดระวังหากคุณกำลังโทรnotifyDataSetChanged()
เพราะมันทำให้ทุกอย่างไม่ถูกต้อง RecyclerView ไม่ทราบว่าตำแหน่งอะแดปเตอร์ของ ViewHolder จนกว่าจะมีการคำนวณเค้าโครงถัดไป ในกรณีนั้นgetAdapterPosition()
จะส่งคืนRecyclerView#NO_POSITION
( -1
)
แต่สมมติว่าคุณโทรnotifyItemInserted(0)
หาgetAdapterPosition()
ViewHolder ซึ่งก่อนหน้านี้อยู่ในตำแหน่ง0
จะเริ่มกลับมา1
ทันที ตราบเท่าที่คุณจัดส่งเหตุการณ์การแจ้งเตือนแบบละเอียดคุณจะอยู่ในสถานะที่ดีเสมอ (เราทราบตำแหน่งอะแดปเตอร์แม้ว่าจะยังไม่ได้คำนวณรูปแบบใหม่ก็ตาม)
อีกตัวอย่างหนึ่งหากคุณกำลังทำอะไรบางอย่างกับการคลิกของผู้ใช้หากgetAdapterPosition()
ส่งคืนNO_POSITION
คุณควรเพิกเฉยต่อการคลิกนั้นเนื่องจากคุณไม่ทราบว่าผู้ใช้คลิกอะไร (เว้นแต่คุณจะมีกลไกอื่น ๆ เช่นรหัสที่เสถียรเพื่อค้นหารายการ)
แก้ไขเมื่อตำแหน่งเลย์เอาต์ดี
สมมติว่าคุณกำลังใช้งานLinearLayoutManager
และต้องการเข้าถึง ViewHolder เหนือรายการที่คลิกในปัจจุบัน ในกรณีนั้นคุณควรใช้ตำแหน่งเค้าโครงเพื่อรับรายการด้านบน
mRecyclerView.findViewHolderForLayoutPosition(myViewHolder.getLayoutPosition() - 1)
คุณต้องใช้ตำแหน่งเค้าโครงเพราะตรงกับสิ่งที่ผู้ใช้กำลังเห็นบนหน้าจอ