Android回收器适配器位置工作不正常:onClick处理不';我不能正常工作
我有一个recycler视图,可以从数据库中获取详细信息。FriendEntity的ArrayList由运行良好的room数据库提供。我想首先为整个列表创建一个未选中的方框图像,如果我点击该图像,它应该会变成一个复选框图像。但当我实现这一点时,当我点击recyclerView的第一项时,我的第16项recyclerView将从未检查更改为已检查,第2项和第17项、第3项和第18项也是如此,依此类推。我不知道这是回收器视图适配器的问题还是其他问题 数据类实体:Android回收器适配器位置工作不正常:onClick处理不';我不能正常工作,android,kotlin,android-recyclerview,Android,Kotlin,Android Recyclerview,我有一个recycler视图,可以从数据库中获取详细信息。FriendEntity的ArrayList由运行良好的room数据库提供。我想首先为整个列表创建一个未选中的方框图像,如果我点击该图像,它应该会变成一个复选框图像。但当我实现这一点时,当我点击recyclerView的第一项时,我的第16项recyclerView将从未检查更改为已检查,第2项和第17项、第3项和第18项也是如此,依此类推。我不知道这是回收器视图适配器的问题还是其他问题 数据类实体: @实体(tableName=“Fri
@实体(tableName=“Friends”)
数据类实体(
@PrimaryKey val friend_名称:字符串,
@ColumnInfo(name=“debt”)val债务:浮动
RecyclerView的ExpenseActivity.xml:
而且,这种行为问题太多了,当我点击第16张图片时,它没有响应。第二次点击会使其取消选中。与第17幅图像相同。我想适配器有点问题
然后,我尝试为单个项目创建一个小视图,这样我的屏幕总共可以显示20个项目。现在,当我点击第一张图片时,第24张被选中,第二次点击会改变第25张。这意味着它单击的项目现在不在视图中,但如何单击
如果有人到现在还不明白,我会在这里为视频粘贴一个GDriveLink:
我想知道如何删除此错误?您面临的问题是由于重新使用视图持有者。最简单的解决方案是在POJO类FriendEntity中创建一个布尔字段
data class FriendEntity (
@PrimaryKey val friend_name: String ,
@ColumnInfo(name = "debt") val debt: Float
val isSelected //To store current status)
现在,在绑定数据时检查此状态,并根据此状态设置复选框
override fun onBindViewHolder(holder: FriendViewHolder, position: Int) {
val itemObject = itemList[position]
//Image selection will be done at binding.
if(itemObject.isSelected){
holder.imgCheck.setImageResource(R.drawable.ic_cb_full)
}else{
holder.imgCheck.setImageResource(R.drawable.ic_cb_empty)
}
holder.txtFriendName.text = itemObject.friend_name
holder.imgCheck.setOnClickListener {
//Just change the status and notify the change.
itemObject.isSelected = !itemObject.isSelected
notifyItemChanged(position)
}
您面临的问题是由于视图持有者的重用。最简单的解决方案是在POJO类FriendEntity中创建一个布尔字段
data class FriendEntity (
@PrimaryKey val friend_name: String ,
@ColumnInfo(name = "debt") val debt: Float
val isSelected //To store current status)
现在,在绑定数据时检查此状态,并根据此状态设置复选框
override fun onBindViewHolder(holder: FriendViewHolder, position: Int) {
val itemObject = itemList[position]
//Image selection will be done at binding.
if(itemObject.isSelected){
holder.imgCheck.setImageResource(R.drawable.ic_cb_full)
}else{
holder.imgCheck.setImageResource(R.drawable.ic_cb_empty)
}
holder.txtFriendName.text = itemObject.friend_name
holder.imgCheck.setOnClickListener {
//Just change the status and notify the change.
itemObject.isSelected = !itemObject.isSelected
notifyItemChanged(position)
}
Aashit Shah提供的答案肯定是一个很好的答案,可以完美地完成这项工作。但以防万一,如果有人不想更改实体类(在我的情况下,我不想在我的POJO/数据类中做任何更改,因为我正在将FriendEntity的整个对象发送到Room数据库),那么您可以进行修改
您可以添加一个布尔数组作为适配器类的成员变量,如下所示
private val boolArray = ArrayList(Collections.nCopies(itemCount,false))
此boolArray将在本地保留布尔状态的记录。
因此,我们可以在BindViewHolder上以与上面相同的方式使用它:
override fun onBindViewHolder(holder: FriendViewHolder, position: Int) {
val itemObject = itemList[holder.adapterPosition]
holder.txtFriendName.text = itemObject.friend_name
holder.imgCheck.setImageResource(if(boolArray[holder.adapterPosition]) R.drawable.ic_cb_full else R.drawable.ic_cb_empty)
holder.imgCheck.setOnClickListener {
if(boolArray[holder.adapterposition]) {
holder.imgCheck.setImageResource(R.drawable.ic_cb_empty)
checkList.remove(itemObject)
boolArray[holder.adapterPosition] = false
} else {
holder.imgCheck.setImageResource(R.drawable.ic_cb_full)
checkList.add(itemObject)
boolArray[holder.adapterPosition] = true
}
}
}
使用此解决方案的优点是,它不会改变您以前的数据库,而且此boolArray的生命周期仅为一个对象,因此具有空间效率。Aashit Shah提供的答案肯定是一个很好的答案,可以完美地完成这项工作。但以防万一,如果有人不想更改实体类(在我的情况下,我不想在我的POJO/数据类中做任何更改,因为我正在将FriendEntity的整个对象发送到Room数据库),那么您可以进行修改
您可以添加一个布尔数组作为适配器类的成员变量,如下所示
private val boolArray = ArrayList(Collections.nCopies(itemCount,false))
此boolArray将在本地保留布尔状态的记录。
因此,我们可以在BindViewHolder上以与上面相同的方式使用它:
override fun onBindViewHolder(holder: FriendViewHolder, position: Int) {
val itemObject = itemList[holder.adapterPosition]
holder.txtFriendName.text = itemObject.friend_name
holder.imgCheck.setImageResource(if(boolArray[holder.adapterPosition]) R.drawable.ic_cb_full else R.drawable.ic_cb_empty)
holder.imgCheck.setOnClickListener {
if(boolArray[holder.adapterposition]) {
holder.imgCheck.setImageResource(R.drawable.ic_cb_empty)
checkList.remove(itemObject)
boolArray[holder.adapterPosition] = false
} else {
holder.imgCheck.setImageResource(R.drawable.ic_cb_full)
checkList.add(itemObject)
boolArray[holder.adapterPosition] = true
}
}
}
使用此变通方法的优点是,它不会更改您以前的数据库,而且此boolArray的生命周期仅为一个对象,因此具有空间效率。视图保持架可以重复使用。您需要在click listener外部(以及内部)的绑定中显式设置复选框。请参阅。视图保持器将被重用。您需要在click listener外部(也可以在内部)显式设置绑定中的复选框。请参见。是的,对于未来的人,只需签出并确保在数据类中使用var isChecked:Boolean=false(尽管顺便说一句,这是可以理解的)。是的,对于未来的人,只需签出并确保var已被选中:Boolean=false在数据类中使用(尽管顺便说一句,这是可以理解的)。