我正在编写一个Android应用程序,该应用程序必须处理RecyclerView中可变数量的元素。添加元素时,一些数据会与UUID一起保存到配置文件中。
无论是在应用程序启动时,还是在运行时用户创建或删除元素时,RecyclerView都会更新并显示所有当前存在的元素。
每个元素都有一个按钮,用于从配置中删除它及其附加数据。当我按下此按钮时,元素数据已成功从配置中删除,并且变成了不可见状态,导致RecyclerView仅显示剩余的元素。
但是,当我尝试插入新元素时,不会显示该元素,而是会显示先前在此会话期间已删除的元素。
一段时间以来,我一直在寻找解决方案。 首先,我开始反复阅读文档,以为我错过了一些东西。我还查看了一些在线示例,说明如何正确地从RecyclerView中删除项目,但无法正常工作。
package com.rappee.protectiveparking.ui
import android.support.v7.widget.RecyclerView
import android.view.LayoutInflater
import android.view.ViewGroup
import com.rappee.protectiveparking.R
import com.rappee.protectiveparking.core.Resources
import java.util.*
class ScrollerAdapter : RecyclerView.Adapter< ConsoleViewHolder >() ,
DragItemTouchHelperAdapter {
private var stockpile: Queue< String > = LinkedList< String >()
private var holder: MutableList< ConsoleViewHolder > = ArrayList()
fun push( identification: String ) {
this.stockpile.add( identification )
this.notifyItemInserted( this.itemCount - 1 )
}
fun remove( position: Int ) {
this.holder.removeAt( position )
this.notifyItemRemoved( position )
}
override fun onCreateViewHolder( parent: ViewGroup , type: Int ): ConsoleViewHolder {
val view: ConsoleViewHolder = ConsoleViewHolder( LayoutInflater.from( parent.context ).inflate( R.layout.console , parent , false ) , this.stockpile.poll() )
this.holder.add( view )
return view
}
override fun onBindViewHolder( holder: ConsoleViewHolder , position: Int ) {
return
}
override fun getItemCount(): Int {
return this.holder.size + this.stockpile.size
}
override fun onItemMove( from: Int , to: Int ): Boolean {
Collections.swap( this.holder , to , from )
for ( i in 0 until this.holder.size ) {
Resources.CONFIGURATION.push( "${this.holder.get( i ).identification}.${Resources.KEY_POSITION}" , "$i" )
}
this.notifyItemMoved( from , to )
return true
}
}
当我尝试插入新元素时,实际上将UUID放入了“库存”并调用了“ notifyItemInserted”,以便激活了“ onCreateViewHolder”。发生这种情况时,我以字符串的形式从'stockpile'中获取最重要的UUID,并将其作为参数提供给'ConsoleViewHolder'的构造函数。 只有当调用此方法时,实际的View才会被推送到RecyclerView中(不是我的决定!)。
但是,当我插入一个新的UUID并在删除某个项目后更新RecyclerView时,不会调用此方法,因此无法显示新的View。 唯一更改的是,先前删除的视图会弹出。
我的问题:如何解决RecyclerView的这种行为,即显示已删除项目而不是新推送项目?
答案 0 :(得分:0)
无需自己保存视图持有人。
它应该看起来像这样:
private var stockpile = MutableList< String >()
fun push( identification: String ) {
stockpile.add( identification )
notifyItemInserted( itemCount - 1 )
}
fun remove( position: Int ) {
stockpile.removeAt( position )
notifyItemRemoved( position )
}
override fun onCreateViewHolder( parent: ViewGroup , type: Int ): ConsoleViewHolder {
val view: ConsoleViewHolder = ConsoleViewHolder( LayoutInflater.from( parent.context ).inflate( R.layout.console , parent , false ) , this.stockpile.poll() )
return view
}
override fun onBindViewHolder( holder: ConsoleViewHolder , position: Int ) {
//replace with something sensible you want to show in your view
view.someTextView.text = stockpile[position].name
return
}
override fun getItemCount(): Int {
return this.stockpile.size
}
我认为您对视图持有者的工作知之甚少。删除private var holder: MutableList< ConsoleViewHolder > = ArrayList()
及其所有引用。请不在onBindViewHolder
以外的地方编辑视图持有人。您遇到的怪异行为是因为您实际上没有从基础stockpile
上删除该项目,然后当您告诉它有新项目时,recyclerview感到困惑,因为您的计数还很遥远。
有关参考实现,请参见https://developer.android.com/guide/topics/ui/layout/recyclerview上的示例。