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()
}