Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/213.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 RecyclerView multiple selection取消选择错误的视图保持架_Android_Kotlin_Android Recyclerview - Fatal编程技术网

Android RecyclerView multiple selection取消选择错误的视图保持架

Android RecyclerView multiple selection取消选择错误的视图保持架,android,kotlin,android-recyclerview,Android,Kotlin,Android Recyclerview,在我的ViewHolder类中,我添加了一个名为isOptionSelected的布尔属性。基本上,此属性的作用是控制是否选择了ViewHolder。我已经这样做了,所有的选项都是默认选择的 在我的OnBindViewHolder()方法中,我为ViewHolder.itemView(它检测任何单击并调用名为OnItemClick()的接口方法)提供了一个onClickListener(): 这是我的OnItemClicked界面: // Interface to use on the main

在我的
ViewHolder
类中,我添加了一个名为
isOptionSelected
的布尔属性。基本上,此属性的作用是控制是否选择了
ViewHolder
。我已经这样做了,所有的选项都是默认选择的

在我的
OnBindViewHolder()
方法中,我为ViewHolder.itemView(它检测任何单击并调用名为
OnItemClick()
的接口方法)提供了一个
onClickListener()

这是我的
OnItemClicked
界面:

// Interface to use on the main activity to detect clicks
interface OnItemClicked {
    fun onItemClick(position: Int, view: View)
}
这是
main活动上的
OnItemClick()
方法:

override fun onItemClick(position: Int, view: View) {
    val vh = menuItemRecyclerView.getChildViewHolder(view) as MeridesAndSaladsAdapter.ViewHolder
    // Invert the boolean value that the vh item holds
    vh.isOptionSelected = !vh.isOptionSelected
}
这是我的
ViewHolder
课程:

class ViewHolder(itemView: View?) : RecyclerView.ViewHolder(itemView) {
    var itemOption: TextView = itemView!!.findViewById(R.id.meridesAndSaladsOption)
    // All options are selected by default
    var isOptionSelected: Boolean = true
}
问题是,当我点击一个
ViewHolder.itemView
时,被取消选择的视图比我点击的视图高出1-2行。在我取消选择一些行,然后尝试选择一些取消选择的行之后,这些选择看起来是随机的。更重要的是,有时当我取消选择或选择某些内容时,一些额外的行也会被更改


我有什么遗漏吗?还是我做错了什么可怕的事情?

您的视图持有者会被重新使用,并在这种情况下将其isOptionsSelected值重置为默认值(True)。您需要存储是否在ViewHolder类之外选择了项目,并在onBindViewHolder中获取/加载该值,可能需要将该值存储为itemOptions对象的一部分。此外,还需要从onClickListeners中切换这些对象(而不是viewholder)的值。

此时,您的viewholder将被重用,并将其IsoptionSelected值重置为默认值(True)。您需要存储是否在ViewHolder类之外选择了项目,并在onBindViewHolder中获取/加载该值,可能需要将该值存储为itemOptions对象的一部分。此外,还需要从onClickListeners中切换这些对象(而不是viewholder)的值。

这个答案基于这样一个事实,即您正在做我知道您不应该做的事情。修复此问题可能无法解决您的问题,但仍然值得指出:

onBindViewHolder()
position
参数不应被视为
final
。换句话说,视图持有者的位置可以随时间变化

您发布的代码包括:

假设视图持有者最初绑定到位置
14
,然后在列表的开头插入两行。您的click listener仍将调用
onimclick(14,it)
,但您的实际位置现在是
16

您可以使用
ViewHolder
上的
getAdapterPosition()
方法来解决此问题。这将为您提供活动位置,而不仅仅是初始位置:

holder.itemView.setOnClickListener {
    clickListener.onItemClick(holder.getAdapterPosition(), it)
    notifyDataSetChanged()
}

更多信息,请参见谷歌IO演示:(时间戳为43:10,他们在这里讨论这个
位置
问题)。

这个答案基于这样一个事实:你正在做一些我知道你不应该做的事情。修复此问题可能无法解决您的问题,但仍然值得指出:

onBindViewHolder()
position
参数不应被视为
final
。换句话说,视图持有者的位置可以随时间变化

您发布的代码包括:

假设视图持有者最初绑定到位置
14
,然后在列表的开头插入两行。您的click listener仍将调用
onimclick(14,it)
,但您的实际位置现在是
16

您可以使用
ViewHolder
上的
getAdapterPosition()
方法来解决此问题。这将为您提供活动位置,而不仅仅是初始位置:

holder.itemView.setOnClickListener {
    clickListener.onItemClick(holder.getAdapterPosition(), it)
    notifyDataSetChanged()
}

有关更多信息,请参阅此Google IO演示文稿:(时间戳为43:10,在这里他们讨论了这个
位置
问题)。

您是否调用过
notifyItemInserted()
notifyItemRemoved()
,或任何其他不只是
notifyDataSetChanged()的
notifyXYZ
方法
?我调用的唯一notifyXYZ方法是您可以看到的方法,即
NOTIFYDATASETCHANGE()
@本普,啊。那么我的回答可能解决不了你的问题。但是知道这一点还是很好的。我想既然我知道我的行不会改变位置,我就可以使用
onBindViewHolder()
提供的
position
,但我想这是一个错误的假设。我还将
notifyDataSetChanged()
更改为
notifyItemChanged(holder.adapterPosition)
,这似乎部分解决了问题。现在,行被取消选择,然后重新选择,如果我第二次点击它们,它们将按预期工作。。。现在,这些行似乎只在第二次点击时起作用。。。知道那可能是什么吗?感谢您对@BenP.的大力支持。!您是否调用过
notifyItemInserted()
notifyItemRemoved()
,或任何其他不只是
notifyDataSetChanged()
notifyXYZ方法?我调用的唯一notifyXYZ方法是您可以看到的方法,即
notifyDataSetChanged()
@本普,啊。那么我的回答可能解决不了你的问题。但是知道这一点还是很好的。我想既然我知道我的行不会改变位置,我就可以使用
onBindViewHolder()
提供的
position
,但我想这是一个错误的假设。我还将
notifyDataSetChanged()
更改为
notifyItemChanged(holder.adapterPosition)
,这似乎部分解决了问题。现在,行被取消选择,然后重新选择,如果我第二次点击它们,它们将按预期工作。。。现在,这些行似乎只在第二次点击时起作用。。。知道那可能是什么吗?感谢您对@BenP.的大力支持。!看来这是正确的
holder.itemView.setOnClickListener {
    clickListener.onItemClick(holder.getAdapterPosition(), it)
    notifyDataSetChanged()
}