Kotlin(Android)中RecyclerView中不需要的复选框选择

Piw*_*iwo 0 checkbox android kotlin android-recyclerview

在我的应用程序中,我有一个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" />
Run Code Online (Sandbox Code Playgroud)

单击该项目时,相应的复选框将设置为选中状态,并将该项目添加到选择列表中。

问题:当我向下滚动并选择一个项目时,再次向上滚动我总是看到另一个复选框已选中。在调试时,我注意到,只有我实际选择的项目已添加到列表中,但是,当在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)
                    }
                }
            }
        }
Run Code Online (Sandbox Code Playgroud)

我的onBindViewHolder()方法包含以下内容:

override fun onBindViewHolder(holder: MyViewHolder?, position: Int) {
            val itemText = dataset[position]
            holder?.text?.text = itemText
        }
Run Code Online (Sandbox Code Playgroud)

Meh*_*t K 5

这可能是由于RecyclerView回收逻辑造成的。向上滚动时,将消失在底部的视图添加到顶部。在您的情况下:带有选中复选框的视图将被回收(绑定)以在其他位置使用,这不是您想要的。要解决此问题,您需要跟踪应选中哪些视图的复选框。仅根据与该视图关联的数据状态来更改该视图中复选框的状态。由于您已经在跟踪应在selectedItems数组中检查的项目,因此只需将以下代码添加到中即可onBindViewHolder

holder?.checkbox?.isChecked = selectedItems.contains(itemText)