我将 RecyclerView ViewHolder 作为复选框,单击该复选框后,我需要取消选择已选中的其他复选框,但它没有发生,更改不会反射(reflect)在 View 中。
回收器项目单击在单击时在 onBindViewHolder 中初始化,插槽数据已更新并调用了 notificationItemChanged,但占位符未更新,我是否错过了更新 View 持有者的任何内容。
override fun onBindViewHolder(
holder: BookingSlotListItemViewHolder,
position: Int,
payloads: MutableList<Any?>
)
class BookingSlotListAdapter(
private val hourSlotHolder: RecyclerView,
private val bookingBtn: TextView
) : RecyclerView.Adapter<BookingSlotListItemViewHolder>() {
private val bookingSlots = ArrayList<BookingSlotAvailability>()
private var lastSelected: Int? = null
private val bookingHourItemAdapter = BookingHourItemAdapter(bookingBtn)
private val NOT_SELECTED_FOR_BOOKING = 0
private val AVAILABLE_FOR_BOOKING = false
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): BookingSlotListItemViewHolder {
val layoutInflater: LayoutInflater = LayoutInflater.from(parent.context)
val view = layoutInflater.inflate(R.layout.booking_time_slot, parent, false)
return BookingSlotListItemViewHolder(view)
}
override fun getItemCount(): Int {
if (bookingSlots.isNullOrEmpty()) {
return 0
}
return bookingSlots.size
}
fun setBookingSlots(bookingSlots: TreeMap<String, Boolean>) {
bookingSlots.map {
this.bookingSlots.add(BookingSlotAvailability(it.key, it.value, NOT_SELECTED_FOR_BOOKING))
}
}
override fun onBindViewHolder(holder: BookingSlotListItemViewHolder, position: Int) {
holder.timeSlot.text = bookingSlots[position].time
if (!bookingSlots[position].isAvailable) {
holder.timeSlot.isEnabled = false
}
if (bookingSlots[position].selectionStatus == 0 && holder.timeSlot.isChecked) {
holder.timeSlot.toggle()
} else if (bookingSlots[position].selectionStatus == 1 && !holder.timeSlot.isChecked) {
holder.timeSlot.toggle()
}
holder.timeSlot.setOnClickListener { view: View? ->
Log.v("CLICKED", "BookingSlotListAdapter: $lastSelected : $position")
val selectedSlot = view as CheckBox
if (lastSelected != null) {
bookingSlots[lastSelected!!].isAvailable = AVAILABLE_FOR_BOOKING
bookingSlots[lastSelected!!].selectionStatus = NOT_SELECTED_FOR_BOOKING
notifyItemChanged(
lastSelected,
bookingSlots[lastSelected!!]
)
}
bookingSlots[position].isAvailable = NOT_AVAILABLE
bookingSlots[position].selectionStatus = SELECTED_FOR_BOOKING
notifyItemChanged(
position,
bookingSlots[position]
)
lastSelected = position
}
}
override fun onBindViewHolder(
holder: BookingSlotListItemViewHolder,
position: Int,
payloads: MutableList<Any?>
) {
super.onBindViewHolder(holder, position, payloads)
Log.v("OVERLOADEDVH", "$payloads $position")
}
}
最佳答案
您需要在 onBindViewholder 方法中对其进行选中/取消选中,因为它会重用 View 并在我们滚动 recyclerView 时再次创建 View ,因此它不知道 checkBox 的最后状态:
// Add these lines below at then end of onBindViewHolder
val selectedSlot = holder.timeSlot as CheckBox
if(lastSelected == position){
selectedSlot.isChecked = true;
}else{
selectedSlot.isChecked = false;
}
要更新旧复选框以取消选择,请调用 notifyDataSetChanged()
,这样将为所有可见单元格再次调用 onBindHolder()
,并相应更新。
在设置 lastSelected
pos 后调用 notifyDataSetChanged()
:
holder.timeSlot.setOnClickListener { view: View? ->
Log.v("CLICKED", "BookingSlotListAdapter: $lastSelected : $position")
val selectedSlot = view as CheckBox
if (lastSelected != null) {
bookingSlots[lastSelected!!].isAvailable = AVAILABLE_FOR_BOOKING
bookingSlots[lastSelected!!].selectionStatus = NOT_SELECTED_FOR_BOOKING
//COMMENT notifyDataSetChanged WILL HANDLE ALL
//notifyItemChanged(
//lastSelected,
//bookingSlots[lastSelected!!]
//)
}
bookingSlots[position].isAvailable = NOT_AVAILABLE
bookingSlots[position].selectionStatus = SELECTED_FOR_BOOKING
//COMMENT notifyDataSetChanged WILL HANDLE ALL
//notifyItemChanged(
// position,
// bookingSlots[position]
//)
lastSelected = position
//------CALL notifyDataSetChanged() for all visible cells------
notifyDataSetChanged() ;
}
关于android - RecyclerView取消选择之前选择的复选框,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57098873/