Android 具有可编辑元素的 Recyclerview 未正确更新新元素

Android Recyclerview with editable elements not updating correctly with new element

所以,我有一个 Recyclerview,其中每个元素都包含一个图标、一个文本视图和一个文本编辑器。

适配器如下所示:

class ZutatenSmallListAdaptermitEingabe internal constructor(
    context: Context, parent: NewRezeptActivity
) : RecyclerView.Adapter<ZutatenSmallListAdaptermitEingabe.ZutatenViewHolder>() {

    private val inflater: LayoutInflater = LayoutInflater.from(context)
    private var zutaten = emptyList<ZutatenData>()
    private var mengenedits = emptyList<RefZutatRezept>()
    private val context = context
    private val parent = parent



    inner class ZutatenViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
        val zutatenItemView: TextView = itemView.findViewById(R.id.textSmallZutat)
        val zutatenPicView: ImageView = itemView.findViewById(R.id.image_SmallZutat)
        var zutatenMengenedit : EditText = itemView.findViewById(R.id.textedit_menge)

    }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ZutatenViewHolder {
        var itemView :View = inflater.inflate(R.layout.recyclerview_item_small_mitmengeeingabe, parent, false)
        return ZutatenViewHolder(itemView)
    }

    override fun onBindViewHolder(holder: ZutatenViewHolder, position: Int) {
        val current = zutaten[position]
        val curpos = position
        holder.zutatenItemView.text = current.zutname
        holder.zutatenPicView.setImageDrawable(ContextCompat.getDrawable(context, current.bild))
        holder.zutatenItemView.setOnClickListener {
                parent.removeZutat(zutaten[position])
        }
        var richtigmengenedit =  mengenedits.firstOrNull() {it.zutatid == current.zutatid}
        if( richtigmengenedit != null) {
            holder.zutatenMengenedit.setText(richtigmengenedit.menge)
        }
        holder.zutatenMengenedit.addTextChangedListener(object : TextWatcher {
            override fun onTextChanged(s: CharSequence, start: Int, before: Int, count: Int){
                mengenedits[curpos].menge =  holder.zutatenMengenedit.text.toString()

            }
            override fun afterTextChanged(s: Editable?) {}

            override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {}
    })
    }

    internal fun setZutaten(zutats: List<ZutatenData>) {
        this.zutaten = zutats
        var neueListe = emptyList<RefZutatRezept>()
        for(zut in zutaten){
            var element = mengenedits.firstOrNull(){it.zutatid == zut.zutatid}
            if( element!= null){
                neueListe += element
            }else{
                neueListe += RefZutatRezept( zut.zutatid, 0, "")
            }
        }
        mengenedits = neueListe
        notifyDataSetChanged()
    }

    override fun getItemCount(): Int = zutaten.size
}

我有一个列表“zutaten”,用于存储要显示的元素,还有另一个列表“mengenedits”,用于存储用户写入文本编辑器的文本。

我还有两个函数可以在列表中添加和删除元素。然后使用 setZutatem.

设置新的 List

当我添加或删除一个元素时,我仍然想在 textedit 中显示正确的文本。 但问题是当“zutaten”列表更新时,“mengedits”列表正确更改,但在 onBindViewHolder 函数中它不知何故变得混乱。第二个元素的文本显示在第一个元素的文本编辑器中。

所以我不确定问题是什么,但我解决了它:

我只是添加和删除某些项目,所以我没有替换整个列表,而是删除或添加了特定项目,而不是调用 notifyDataSetChanged(),我只是调用了 notifyItemInserted 和 notifyItemRemoved

因此删除添加的函数如下所示:

    fun addZutat(zutat: ZutatenData){
        zutaten.add(zutat)
        mengenedits.add( RefZutatRezept( zutat.zutatid, 0, ""))
        notifyItemInserted(zutaten.size -1)
    }

    fun removeZutat(zutat: ZutatenData){
        val pos = zutaten.indexOf(zutat)
        zutaten.removeAt(pos)
        mengenedits.removeAt(pos)
        notifyItemRemoved(pos)
    }

注意:我还将列表更改为 MutableLists,因为我想调用 removeAt()