**问题是这样的:我按下按钮删除列表中的一个项目,它被删除了。但是当我旋转屏幕时,列表会重新加载。列表不保存数据。
LiveData 看不到变化。如何通过它传递一个包含已删除元素的新列表?我花了 10 个小时解决这个问题 (**
适配器
class ItemAdapter(var context: Context, private var arrayList: MutableList<NumberModel>):RecyclerView.Adapter<ItemAdapter.ItemHolder>() {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ItemHolder{
val itemHolder = LayoutInflater.from(parent.context).inflate(
R.layout.grid_layout_list_item,
parent,
false
)
return ItemHolder(itemHolder)
}
override fun onBindViewHolder(holder: ItemHolder, position: Int) {
var positionOfNumber:NumberModel = arrayList.get(position)
holder.textOfNumber.text = positionOfNumber.numberOfElement
holder.button.setOnClickListener {
var positionForDelete = holder.adapterPosition
arrayList.removeAt(positionForDelete)
notifyItemRemoved(positionForDelete)
notifyItemRangeChanged(positionForDelete,arrayList.size)
}
}
override fun getItemCount(): Int {
return arrayList.size
}
class ItemHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
var textOfNumber = itemView.findViewById<TextView>(R.id.numberTextView)
var button:Button = itemView.findViewById(R.id.buttonClick)
}
主事件
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val list = mutableListOf<NumberModel>()
adapter = ItemAdapter(this,list)
recyclerView = findViewById(R.id.recyclerViewList)
gridLayoutManager = GridLayoutManager(applicationContext,2,LinearLayoutManager.VERTICAL,false)
recyclerView?.layoutManager = gridLayoutManager
recyclerView?.setHasFixedSize(true)
recyclerView?.adapter = adapter
val model= ViewModelProvider(this).get(MainActivityViewModel::class.java)
model.getListElements().observe(this, Observer {elementsSnapshot ->
// Received elements from ViewModel
list.clear()
// Take new data from snapshot
list.addAll(elementsSnapshot)
adapter?.notifyDataSetChanged()
})
}
View 模型
class MainActivityViewModel : ViewModel() {
private val elementsList: MutableLiveData<MutableList<NumberModel>>
init {
elementsList = MutableLiveData()
elementsList.value = setElements()
}
fun getListElements() : LiveData<MutableList<NumberModel>>{
return elementsList
}
private fun setElements() : MutableList<NumberModel> {
val itemArrayList:MutableList<NumberModel> = ArrayList()
itemArrayList.add(NumberModel("1"))
itemArrayList.add(NumberModel("2"))
itemArrayList.add(NumberModel("3"))
itemArrayList.add(NumberModel("4"))
itemArrayList.add(NumberModel("5"))
return itemArrayList
}
最佳答案
改变从 ViewModel 返回的对象很少是个好主意。对事件的 react (例如用户单击您的删除按钮)应该在 ViewModel 中完成。这与响应式 UI 风格(数据下降,事件上升)一致,并且允许您将逻辑 (ViewModel) 与 UI 细节(Activity、Adapter)分开。
您的 ViewModel 可以公开两个元素:
class MyViewModel {
private val localElements = MutableLiveData<List<...>>()
val elements: LiveData<List<...>>
get() = localElements
fun onElementClicked(index: Int) {
// get current value of localElements, make a copy of it with removed value at [index] and publish it to localElements
}
}
然后,您可以在 Adapter 中公开 setElements
方法,并调用它以响应 viewModel.elements
更改。您可以将 ViewModel 的实例传递给您的适配器,并在检测到点击时调用 onElementClicked
。
这样,您就可以将 Activity 和 Adapter 视为基本上是“无状态的”。当配置更改时,有效状态将保留在您的 ViewModel 中。
附言。 Android 文档建议在构建事件/片段期间检索您的 ViewModel 实例:https://developer.android.com/jetpack/guide?authuser=1#build-ui
关于android-studio - 如何在 RecyclerView 上使用 LiveData?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65726850/