7

I have a shared viewmodel in multiple fragments.

class MainFragment {
      private val sharedViewModel: HomeActivityViewModel by activityViewModels()
}

class MagazinesFragment {
      private val sharedViewModel: HomeActivityViewModel by activityViewModels()
}

And I have an event within that shared view model.

class HomeActivityViewModel{
       val userAuthStatusChanges = MutableLiveData<Boolean>()
}

And I am observing that event in multiple fragments.

 class MainFragment {
       //...
          sharedViewModel.userAuthStatusChanges.observe(viewLifecycleOwner) {
            // do smth
        }
    }
    
 class MagazinesFragment {
         //...
          sharedViewModel.userAuthStatusChanges.observe(viewLifecycleOwner) {
            // do smth
        }
    }

Whenever that userAuthStatusChanges event happens, I want to fire single live event in all fragments that are observing that event.

If I make the event MutableLiveData, the event gets observed whenever fragment is recreated. If I use SingleLiveEvent, the event gets observed only one time and only in one fragment.

I want this event triggered in all fragments and only one time in each fragment. I am using navigation component.

SpiralDev
  • 7,011
  • 5
  • 28
  • 42
  • since you want only one event why not use the Fragment Result API ? https://developer.android.com/guide/fragments/communicate#fragment-result – prudhvir3ddy Aug 18 '21 at 06:58
  • @prudhvir3ddy This won't work because this result is consumed only one time in one fragment only – SpiralDev Aug 18 '21 at 07:56
  • So , you basically want the livedata to be observed in all fragment , but the task that is to be performed post successfull authentication to be performed only once irrespective of the fragment , right ? – Karunesh Palekar Aug 18 '21 at 08:08
  • @KARUNESHPALEKAR No, I want the task to be performed in ALL fragments, but only one time in all fragments – SpiralDev Aug 18 '21 at 08:19
  • maybe a SharedFlow will do it? but I haven't tried anything with it, this is just a suggestion :) https://developer.android.com/kotlin/flow/stateflow-and-sharedflow#sharedflow – cd1 Aug 18 '21 at 08:34
  • Lifecycle awareness would break this, you are looking to use an EventBus in this particular case. LiveData would not work – EpicPandaForce Aug 18 '21 at 21:02
  • @SpiralDev Did u get any solution?. if, then pls do share – abby May 24 '22 at 14:39
  • @abby Have a look at how single events are mapped to ViewModelStore [here](https://github.com/Flywith24/WrapperLiveData/blob/21be6925d97cbad1c7f57c35f25bb823b1eecb6f/library/src/main/java/com/flywith24/wrapperlivedata/Event.kt) – SpiralDev May 24 '22 at 15:46

1 Answers1

0

You can do like this ,

private val _userAuthStatusChanges = MutableLiveData<Boolean>()
val userAuthStatusChanges: LiveData<Boolean> = _userAuthStatusChanges

fun changeStatus(value: Boolean) {
    _userAuthStatusChanges.postValue(value)
}

Observe the Live Data and whenever you want to change the value, call the changeValue() function.

If you want to give some initial value you can add init block.

Like this ,

init {
    _userAuthStatusChanges.postValue(false)
}
Vaibhav Goyal
  • 1,692
  • 1
  • 8
  • 23
  • Here the live data gets observed whenever fragment is recreated, I want it to be observed only one time in each fragment. – SpiralDev Aug 18 '21 at 14:14