Kotlin中如何在ViewModel类中保留MutableList的历史数据
解决方案
问题根源
- ViewModel作用域错误:当前以Fragment作为ViewModel的作用域,每次Fragment从详情页返回重建时,都会创建新的
ShoesViewModel实例,init方法会重新初始化列表,导致之前添加的数据丢失。 - LiveData未触发更新:向MutableList添加元素后,由于List的引用未改变,LiveData不会自动通知观察者数据变化。
- 列表重复添加:
loadShoes方法每次收到数据就直接追加所有元素,未清空原有View,会导致重复显示。
具体修改步骤
1. 调整ViewModel作用域,复用同一实例
在ShoesList.kt中,获取ViewModel时使用Activity作为作用域,确保ViewModel不会随Fragment销毁重建:
// 替换原ViewModel获取代码 viewModel = ViewModelProvider(requireActivity(), viewModelFactory).get(ShoesViewModel::class.java)
2. 修改ViewModel初始化与数据更新逻辑
修改ShoesViewModel.kt,仅首次创建时加载默认数据,并在添加新元素后手动通知LiveData更新:
class ShoesViewModel(_newShoe: String?=null): ViewModel() { private var _shoesList = MutableLiveData<MutableList<String>>() init { // 仅当列表未初始化时加载默认数据 if (_shoesList.value.isNullOrEmpty()) { _shoesList.value = mutableListOf( "trade", "calendar", "sad", "desk", "guitar", "home", "railway", "zebra", "jelly", "car", "crow", "trade", "bag", "roll" ) } // 初始化时传入新单词则直接添加 _newShoe?.let { save(it) } } val shoesList: LiveData<MutableList<String>> get() = _shoesList fun save(newShoe: String){ _shoesList.value?.add(newShoe) // 手动通知LiveData数据变化 _shoesList.postValue(_shoesList.value) } }
3. 修复列表加载逻辑,避免重复显示
修改ShoesList.kt中的loadShoes方法,加载前先清空原有View:
private fun loadShoes(list: MutableList<String>){ // 清空LinearLayout原有子View binding.linearlayoutShoelist.removeAllViews() for(shoe in list){ val newTextViewShoe = TextView(context) newTextViewShoe.text = shoe binding.linearlayoutShoelist.addView(newTextViewShoe) } }
4. 移除Fragment中重复的保存调用
删除ShoesList.kt中重复的viewModel.save(shoesListArgs.newShoe),因为ViewModel的init已经处理了传入的新单词:
// 移除该行代码 // viewModel.save(shoesListArgs.newShoe)
内容的提问来源于stack exchange,提问作者Andressa Pinheiro
相关产品推荐
相关产品推荐

