Alfredo Bejarano
Alfredo Bejarano

Reputation: 588

How does LiveData works in this case?

before anything else, i'm not asking for the solution (code) to this problem, Im asking for a correction in my understanding in LiveData, as I think im missing something.

As far as I know, LiveData´s onActive function triggers everytime an Observer (LifeCycleOwner) gets active, long story short, in the onCreate method for an Activity or Fragment.

This is the issue im dealing with right now.

Im using the Android Navigation Component, I have my Activity A that holds a navigation graph, in this graph, two fragments share common logic, so, instead of creating Interfaces for communicating between each other, im using a ViewModel, for simplicity sake, lets call it ActivityAViewModel.

Now, this VM contains the following.

ActivityAViewModel.kt

// Private Mediator LiveData
private val mediatorLD = MediatorLiveData<Boolean>()

// Public immutable access of the mediator LiveData
fun mediatorLD(): LiveData = mediatorLD

// Representation of what the transformation is doing.
fun doFoo() {
   val workLD: LiveData<WrapperClass<Boolean>> = repository.someWork()
   Transformations.map(workLD) { wrappedResult ->
      mediatorLD.postValue(wrappedResult.myBoolean)
   }
}

Now, the LiveData version of the MutableLiveData is being observed by two UI controllers, MyFragmentB.kt and MyFragmentC.kt, the problem Im having is that when MyFragmentB executes doFoo(), it receives the result accordingly, no issues there, but when I navigate to MyFragmentC.kt, the same result is reported to C and viceversa.

I don't want this to happen, If FragmentB already observed the change, I dont wan't C to listen for that change.

I kind of understand why it is happening.

As far as I know, LiveData´s onActive function triggers everytime an Observer (LifeCycleOwner) gets active, long story short, in the onCreate method for an Activity or Fragment.

As a change has been detected using postValue, the ViewModel is waiting for its observers to be active in order to dispatch the results.

When the navigation to the other fragment is performed, the observer gets ready, triggering onActive and detecting the change.

Is there a way to prevent the two fragments receiving the result? I mean, when one of those two receives the result, the other wont listen to it?

Upvotes: 0

Views: 250

Answers (1)

Arka Prava Basu
Arka Prava Basu

Reputation: 2560

You would want to design this event accordingly, pretty much similar to the Event Wrapper discussed in the blog post shared by Jeel.

https://medium.com/androiddevelopers/livedata-with-snackbar-navigation-and-other-events-the-singleliveevent-case-ac2622673150

The basic idea would be Event would be consumed only once. You can then wrap this with a LiveData. When you set a new Event in your LiveData the observers will be notified of it, after the first consumption of the new event subsequent consumptions would not return any value.

Upvotes: 2

Related Questions