Reputation: 93
I have a pretty straightforward question about LiveData. I have a MutableLiveData<MutableList<Car>>
and I want to update a specific field in my list, so I guess that when the field is updated, the MutableLiveData should trigger the observers but that does not happen.
So if I use this line of code my observers are not triggered.
var carList = MutableLiveData<MutableList<Car>>()
...
carList.value?.set(car.id,Car(car.id, color))
But if I do something like this the observers are triggered.
var carList = MutableLiveData<MutableList<Car>>()
...
var newList = carList.value
carList?.set(car.id,Car(car.id, color))
carList.value = newList
Can please somebody explain why this happens? Is it essential to give a whole new list to the livedata to be triggered or there is something I am missing? Thank you in advance.
Upvotes: 1
Views: 1572
Reputation: 1791
If you assign a new MutableList
to the wrapped value of MutableLiveData
then it will notify its observers but if you add/delete any items of its wrapped value it will not notify its observers because the wrapped value has same MutableList
object reference. Thus your second case is notifying where your first case does not notify. You can overcome this problem by making an extension of MutableLiveData
as follows:
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()
}
}
Then add/remove items from your MutableLiveData
like:
// 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))
Upvotes: 2