LaVOZs

The World’s Largest Online Community for Developers

'; android - How does LiveData works in this case? - LavOzs.Com

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.

  • A private, MediatorLiveData for this VM to report values to
  • A public function that returns this MediatorLiveData as a LiveData, preventing the UI controllers from modifying its value
  • A function that does some work, this work returns a LiveData, a Transformation is used for the LiveData returned by the work, returns the necessary UI data.
  • It looks something like this:

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?

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.

Related
Proper use cases for Android UserManager.isUserAGoat()?
Observing LiveData from ViewModel
LiveData Observer not Called
Data binding LiveData from Transformation - Android Kotlin
Multiple LiveData Observers After Popping Fragment
Android - LiveData doesn't get updated