You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Kotlin中如何在ViewModel类中保留MutableList的历史数据

解决方案

问题根源

  1. ViewModel作用域错误:当前以Fragment作为ViewModel的作用域,每次Fragment从详情页返回重建时,都会创建新的ShoesViewModel实例,init方法会重新初始化列表,导致之前添加的数据丢失。
  2. LiveData未触发更新:向MutableList添加元素后,由于List的引用未改变,LiveData不会自动通知观察者数据变化。
  3. 列表重复添加: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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.04 14:20:59