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()
所以,我有一个 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()