Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/kotlin/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android回收器适配器位置工作不正常:onClick处理不';我不能正常工作_Android_Kotlin_Android Recyclerview - Fatal编程技术网

Android回收器适配器位置工作不正常:onClick处理不';我不能正常工作

Android回收器适配器位置工作不正常:onClick处理不';我不能正常工作,android,kotlin,android-recyclerview,Android,Kotlin,Android Recyclerview,我有一个recycler视图,可以从数据库中获取详细信息。FriendEntity的ArrayList由运行良好的room数据库提供。我想首先为整个列表创建一个未选中的方框图像,如果我点击该图像,它应该会变成一个复选框图像。但当我实现这一点时,当我点击recyclerView的第一项时,我的第16项recyclerView将从未检查更改为已检查,第2项和第17项、第3项和第18项也是如此,依此类推。我不知道这是回收器视图适配器的问题还是其他问题 数据类实体: @实体(tableName=“Fri

我有一个recycler视图,可以从数据库中获取详细信息。FriendEntity的ArrayList由运行良好的room数据库提供。我想首先为整个列表创建一个未选中的方框图像,如果我点击该图像,它应该会变成一个复选框图像。但当我实现这一点时,当我点击recyclerView的第一项时,我的第16项recyclerView将从未检查更改为已检查,第2项和第17项、第3项和第18项也是如此,依此类推。我不知道这是回收器视图适配器的问题还是其他问题

数据类实体:

@实体(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在数据类中使用(尽管顺便说一句,这是可以理解的)。