【发布时间】:2018-08-14 19:34:26
【问题描述】:
在我的应用程序中,我有一个 RecyclerView,其中包含 15 个静态项目,包括一个 TextView 和一个 CheckBox:
<android.support.v7.widget.RecyclerView
android:id="@+id/list"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginBottom="82dp"
android:layout_marginEnd="8dp"
android:layout_marginStart="8dp"
android:scrollbars="vertical" />
点击项目时,相应的复选框被设置为选中,项目被添加到选择列表中。
问题: 当我向下滚动并选择一个项目时,再次向上滚动我总是看到另一个复选框被选中。在调试时我注意到,只有我实际选择的项目被添加到列表中,但是当在 UI 中随机检查/“选择”其他项目时,它仍然是一个糟糕的用户体验。
我怎样才能阻止这种奇怪的行为?
我正在使用视图持有者来管理项目视图:
private inner class MyViewHolder(view: View) : RecyclerView.ViewHolder(view) {
val checkBox: CheckBox = view.findViewById(R.id.checkbox)
val text: TextView = view.findViewById(R.id.text)
init {
view.setOnClickListener { checkBox.isChecked = !checkBox.isChecked }
checkBox.setOnCheckedChangeListener { _, isChecked ->
val itemText = dataset[adapterPosition]
logger.debug("state change $isChecked for $itemText")
if (isChecked) selectedItems.add(itemText)
else {
if (selectedItems.contains(itemText)) selectedItems.remove(itemText)
}
}
}
}
我的 onBindViewHolder() 方法包含以下内容:
override fun onBindViewHolder(holder: MyViewHolder?, position: Int) {
val itemText = dataset[position]
holder?.text?.text = itemText
}
【问题讨论】:
-
这可能是因为 RecylerView 回收逻辑。当您向上滚动时,会在顶部添加一个消失在底部的视图。在您的情况下:选中复选框的视图被回收(绑定)以在另一个位置使用,这不是您想要的。这可以使用 onBindViewHolder 调用修复,并根据每次绑定时的数据状态装饰 UI。介意分享一下你的逻辑吗?
-
@MehmetKologu 是对的。您的“onBindViewHolder”机制应确保为 CheckBox 设置正确的文本和选中状态。如果您可以在那里发布您的实现,那将会很有帮助。另外作为旁注,在您的最后一行检查
if (selectedItems.contains(itemText))是相当多余的。你可以打电话给selectedItems.remove(itemText)。如果不包含该项目,则没有任何作用。 -
感谢@Mehmet 的澄清。我将 onBindViewHolder-sn-p 添加到帖子底部
-
只需在 onBind 方法中添加一行来设置复选框值。这应该如下所示:
itemText holder?.checkBox?.setChecked(selectedItems.contains(dataset[position]))。希望这会有所帮助 -
在您的 onBindViewHolder 中,您将文本设置为正确的文本。您还需要以相同的方式设置复选框的状态。这可能意味着重新考虑您的数据集包含什么,或者通过您的 selectedItems 来决定是否需要检查当前项目的复选框。
标签: android checkbox android-recyclerview kotlin