Android RecyclerView Manejo de datos usando Kotlin: índice de cambio de filas después de la modificación

Estoy escribiendo mi primer proyecto de Android en Kotlin y tengo dificultades con recyclerView.

MutableList <String> se utiliza como fuente de datos para mi adaptador, y tiene un modo de edición y un modo normal.

onCreateViewHolder () infla una vista con un editText dentro, y luego crea un titular de vista para mantener esta vista.

ViewHolder tiene una function bindSkill () que contiene mi lógica.

onBindViewHolder () llama a viewHolder.bindSkill ()

bindSkill () tiene la lógica para la transición entre EditMode y Normal Mode.

Tres cosas deberían suceder cuando configuro EditMode en verdadero:

  1. Los campos EditText deben establecerse en .isEnable = true (lo que permite al usuario editar los campos de text)
  2. Los campos EditText deberían establecerse en .background = R.drawable.m_gray_border (para mostrar al usuario los campos de text)
  3. Cargar text de mStringMutableList (si es necesario?)

Cuando se presiona nuevamente, se supone que se debe ejecutar el process inverso (con algunas modificaciones:

  1. Los campos EditText deben establecerse en .isEnable = false
  2. Los campos EditText deberían establecerse en .background = null (para ocultar el borde de los campos de text)
  3. ¿Guardar text de mStringMutableList (si es necesario?)
  4. Formato de cadena para hacer una list de viñetas con •% 1 $ s

El problema

Al cargar el adaptador con mis datos, se escribe sobre las cadenas vacías en los campos de text de edición.

Además, cuando voy al modo de edición y cambio un campo de text, las filas recycleView comienzan a cambiar de lugar. El text cambia según lo esperado y se almacena y formatea, pero se mueve a un nuevo índice.

Si llena todos los campos de text, se invertirán, pero si cambia solo unos pocos, parece que cambian de lugar en un asunto aleatorio.

¿Existe una práctica común para este tipo de problemas? Se ve tan simple, pero no puedo entenderlo.

¡Cualquier ayuda es apreciada!

El código

Actividad:

class ProfileActivity : BaseActivity() { private lateinit var recyclerViewProfile: RecyclerView private lateinit var linearLayoutManager: LinearLayoutManager private lateinit var skillAdapter: SkillListAdapter override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_profile) toolBar.rightButton.setOnClickListener { beginEdit() } recyclerViewProfile = findViewById(R.id.recyclerView) linearLayoutManager = LinearLayoutManager(this) recyclerViewProfile.layoutManager = linearLayoutManager skillAdapter = SkillListAdapter(mutableListOf("skill1", "skill2", "skill3", "skill4", "skill5")) recyclerViewProfile.adapter = skillAdapter recyclerViewProfile.itemAnimator = DefaultItemAnimator() } private fun beginEdit() { rightButton.setOnClickListener { doneEditing() } skillAdapter.isEditMode = true toolBar.rightButton.text = getString(R.string.save) skillAdapter.notifyDataSetChanged() } private fun doneEditing() { skillAdapter.isEditMode = false toolBar.rightButton.text = getString(R.string.edit) rightButton.setOnClickListener { beginEdit() } skillAdapter.notifyDataSetChanged() } } 

Adaptador:

 class SkillListAdapter(private var skills: MutableList<String>) : RecyclerView.Adapter<SkillListAdapter.SkillHolder>() { var isEditMode: Boolean = false override fun onCreateViewHolder(parent: ViewGroup, position: Int): SkillHolder { val inflatedView = parent.inflate(R.layout.recycler_item_row) return SkillHolder(inflatedView) } override fun onBindViewHolder(skillHolder: SkillHolder, position: Int) { if (!isEditMode) { skills[position] = skillHolder.skillName.text.toString() } skillHolder.bindSkill(isEditMode, skills[position]) } override fun getItemCount(): Int = skills.size class SkillHolder(view: View) : RecyclerView.ViewHolder(view) { var skillName = view.recycleSkillEditText!! private var boxes = view.recyclerViewCheckBoxes!! init { skillName.setText("") } fun bindSkill(isEditMode: Boolean, SkillName: String) { if (isEditMode) { //begin editing [EDIT MODE] skillName.setText(SkillName) skillName.isEnabled = true skillName.background = itemView.context.getDrawable(R.drawable.rect_rounded_border_gray) boxes.visibility = View.VISIBLE } else { //done editing [NORMAL MODE] skillName.setText(String.format(itemView.context.getString(R.string.bulletPointFormat), SkillName)) skillName.isEnabled = false skillName.background = null boxes.visibility = View.GONE } } } }