Kotlin中List随另一列表更新:RecyclerView适配器数据未赋值却自动同步
问题根因
该现象由Kotlin集合引用传递直接导致,核心问题存在两处:
- ViewModel中定义的
devices是MutableLiveData<MutableList<DataModelDevice>>类型,你更新数据时应该是直接修改了原有MutableList对象的内容,再调用setValue/postValue触发观察者回调,此时LiveData携带的列表和适配器内部持有的devices是同一个内存引用的对象 - 适配器的
setDevices方法优先执行了DiffUtil差异计算,此时传入的新列表和适配器原有列表指向同一内存地址,内容自然完全一致,差异计算逻辑直接失效,最后给this.devices赋值的操作也属于无意义操作
修复方案
按照以下步骤修改即可解决问题:
- 优先将ViewModel中的LiveData修改为不可变集合类型,从源头上避免引用被意外修改:
// 内部用MutableLiveData处理更新,对外暴露不可变LiveData private val _devices = MutableLiveData<List<DataModelDevice>>() val devices: LiveData<List<DataModelDevice>> = _devices
- 每次更新ViewModel中的列表数据时,生成新的集合对象再赋值给LiveData,禁止直接修改原有列表内容:
// 错误写法:直接修改原有MutableList内容 // val oldList = _devices.value ?: mutableListOf() // oldList.add(newDevice) // _devices.value = oldList // 正确写法:生成全新的列表对象 val oldList = _devices.value ?: emptyList() val newList = oldList.toMutableList().apply { // 执行新增、删除、修改等所有列表操作 add(newDevice) } _devices.value = newList
- 适配器侧的
setDevices逻辑可以保持不变,此时传入的tempDevices是全新的列表引用,DiffUtil可以正常计算新旧列表的差异。
补充说明
如果业务场景必须使用MutableList,那么每次给LiveData赋值时也需要调用toList()方法生成新的列表副本,保证新旧列表是独立的内存引用,避免引用共享导致的DiffUtil失效问题。
内容的提问来源于stack exchange,提问作者Zubair Akber
相关产品推荐
相关产品推荐

