Selecciones no deseadas en RecyclerView

En mi aplicación tengo un RecyclerView que contiene 15 elementos estáticos que constan de un TextView y un 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" /> 

Al hacer clic en el elemento, la casilla correspondiente se establece en marcada y el elemento se agrega a una list de selección.

El problema : cuando me desploop hacia abajo y selecciono un elemento, me desploop hacia arriba otra vez. Siempre veo otra casilla marcada. Mientras realizaba la debugging, me di count de que solo se ha agregado a la list mi elemento seleccionado en realidad, pero no obstante es una mala experiencia para el usuario cuando se seleccionan / seleccionan otros elementos en la IU de forma aleatoria.

¿Cómo puedo detener este extraño comportamiento?

Estoy usando un titular de vista para administrar las vistas de elementos:

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

Mi método onBindViewHolder () contiene lo siguiente:

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

Esto está sucediendo probablemente debido a la lógica de reciclado de RecyclerView. Cuando te desplazas hacia arriba, una vista que desaparece en la parte inferior se agrega a la parte superior. En su caso: la vista con una checkbox marcada se recicla (encuaderna) para ser utilizada en otro lugar, que no es lo que desea. Para solucionar esto, necesita mantener el seguimiento de las vistas que deberían tener una casilla marcada. Solo cambie el estado de la checkbox en una vista dependiendo del estado de datos asociado con esa vista. Como ya está haciendo un seguimiento de los elementos que deben verificarse en la matriz selectedItems , simplemente agregue el siguiente código a onBindViewHolder .

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

  • Desadaptación del tipo de Kotlin: ¡tipo inferido es Ver! pero se esperaba TextView
  • RecyclerView: implementa correctamente la eliminación de SnackBar UNDO (Kotlin)
  • ¿Por qué onclick en los ítems de RecyclerView se devuelve una identificación de artículo incorrecta?
  • Genéricos para RecyclerView.Adapter Android
  • kotlin RecyclerViewAdapter IndexOutOfBoundException
  • Android solo estableceStackFromEnd solo si RecycleView / List es más grande que la pantalla
  • Haga que los niños de RecyclerView coincidan con la altura de los padres cuando usan el constructor en lugar de inflar para crearlos
  • La vista de reciclador no se infló. Obteniendo el error "Sin adaptador conectado, omitiendo el layout"
  • RecyclerView animation de elementos, se llama AnimationFinished, pero no está activado en AnimationStarted. ¿Por qué?
  • ReciclarVer list de elementos que no aparecen
  • Kotlin: esperando la statement de un miembro