3

Say my LiveData looks like this LiveData<List<Dog>> dogsLiveData = ...

When I make a change to a property of a Dog object, I want the observer of the LiveData to be notified. How do I do that?

public void doChange(){
   List<Dog> dogs = dogsLiveData.value;
   Dog d = dogs.get(1);
   d.setLegs(5); //I want this to trigger notification. How?
}

(leg changed from 4 to 5 in the example)

Mwen Rele
  • 93
  • 1
  • 8
  • LiveData works well with immutable state because of this reason. If you update one of the items in the list, how is the list supposed to know what changes you made. In case of an immutable list, you'd actually create a new list and post that value to LiveData. – Froyo Jun 19 '19 at 02:05

2 Answers2

0

You may have a MutableLiveData instead of LiveData to be able to set new values. According to Android Documentation , LiveData is immutable and MutableLiveData extends LiveData and is mutable.

So you need to change from LiveData<List<Dog>> to MutableLiveData<List<Dog>>

Also, in your ViewModel, create a method for the list observable:

 public LiveData<List<Dog>> getDogsObservable() {
        if (dogsLiveData == null) {
            dogsLiveData = new MutableLiveData<List<Dog>>();
        }
        return dogsLiveData;
 }

And finally on your MainActivity or whatever activity which holds the ViewModel add this piece of code:

viewModel.getDogsObservable().observe(context, dogs -> { //Java 8 Lambda
    if (dogs != null) {
       //Do whatever you want with you dogs list
    }
}
Dimas Mendes
  • 2,664
  • 1
  • 21
  • 19
-1

The only way is to re-assign the live data value, it won't trigger on changes to the list's elements.

public void doChange(){
   List<Dog> dogs = dogsLiveData.value;
   Dog d = dogs.get(1);
   d.setLegs(5);
   dogsLiveData.value = dogs
}
Francesc
  • 25,014
  • 10
  • 66
  • 84
  • I tried that but it didn't work. The only way to make it work is to literally change the actual list. I was hoping there was some sort of simple method I could call to force the trigger. so basically I can do `dogsLiveData.value = new ArrayList<>(); dogsLiveData.value = dogs;`. And that combo will work. It's just strange. – Mwen Rele Jun 19 '19 at 01:07
  • It does not work because LiveData checks for equality based on reference when you post a new update. When you assign it a new list and then assign the old list again, the LiveData value has changed and hence it notifies the observer. – Froyo Jun 19 '19 at 02:02