更新列表项时不会触发实时数据

Livedata is not triggered when List item is getting updated

我有一个关于 LiveData 的非常简单的问题。我有一个 MutableLiveData<MutableList<Car>> 并且我想更新列表中的特定字段,所以我猜想当更新该字段时,MutableLiveData 应该触发观察者,但这并没有发生。

所以如果我使用这行代码,我的观察者不会被触发。

var carList = MutableLiveData<MutableList<Car>>()
...
carList.value?.set(car.id,Car(car.id, color)) 

但是如果我这样做,观察者就会被触发。

var carList = MutableLiveData<MutableList<Car>>()
...
var newList = carList.value
carList?.set(car.id,Car(car.id, color))
carList.value = newList 

有人能解释一下为什么会这样吗?是否必须为要触发的实时数据提供一个全新的列表,或者我遗漏了什么?提前谢谢你。

如果您将新的 MutableList 分配给 MutableLiveData 的包装值,那么它会通知其观察者,但如果您 add/delete 其包装值的任何项目,它将不会通知其观察者观察者,因为包装值具有相同的 MutableList 对象引用。因此,您的第二个案例正在通知您的第一个案例没有通知的地方。您可以通过扩展 MutableLiveData 来克服这个问题,如下所示:

fun <T> MutableLiveData<MutableList<T>>.addNewItem(item: T) {
    val oldValue = this.value ?: mutableListOf()
    oldValue.add(item)
    this.value = oldValue
}

fun <T> MutableLiveData<MutableList<T>>.addNewItemAt(index: Int, item: T) {
    val oldValue = this.value ?: mutableListOf()
    oldValue.add(index, item)
    this.value = oldValue
}

fun <T> MutableLiveData<MutableList<T>>.removeItemAt(index: Int) {
    if (!this.value.isNullOrEmpty()) {
        val oldValue = this.value
        oldValue?.removeAt(index)
        this.value = oldValue
    } else {
        this.value = mutableListOf()
    }
}

然后 add/remove 个来自你 MutableLiveData 的项目,例如:

// Here is your car list
var carList = MutableLiveData<MutableList<Car>>()

// Add new item to your car list
carList.addNewItem(Car(car.id, color))

// Delete an item from car list at position i
carList.removeItemAt(i)

// Add new item to your car list at position i
carList.addNewItemAt(i, Car(car.id, color))