Reputation: 1941
I have MainActivity which is containing 5 Fragments (FragmentA, FragmentB, FragmentC....E) with ViewPager. FragmentA has viewModel and observing a MutableLiveData called "showPopupSuccess" which set to true after doing a task.
The problem is when i go to FragmentC and then get back to FragmentA. The popup is showing again because the observer looks like "reactivated". How to get rid of this? I want the mutableLiveData get resetted. So it has no value in it and not showing a popup
This is the video of the bug if you want to see further https://www.youtube.com/watch?v=Ay1IIQgOOtk
Upvotes: 2
Views: 1271
Reputation: 508
The easiest way to solve your issue: Use the Event
wrapper
Instead of "resetting" the LiveData
, you can mark its content as handled
when you observe it for the first time. Then your repeated observations know it has already been handled and can ignore it.
To create a better answer according to the guidelines I'm copying over the relevant information from the linked article:
The wrapper:
/**
* Used as a wrapper for data that is exposed via a LiveData that represents an event.
*/
open class Event<out T>(private val content: T) {
var hasBeenHandled = false
private set // Allow external read but not write
/**
* Returns the content and prevents its use again.
*/
fun getContentIfNotHandled(): T? {
return if (hasBeenHandled) {
null
} else {
hasBeenHandled = true
content
}
}
/**
* Returns the content, even if it's already been handled.
*/
fun peekContent(): T = content
}
In the ViewModel:
// Instead of Boolean the type of Event could be popup
// parameters or whatever else.
private val _showSuccess = MutableLiveData<Event<Boolean>>()
val showSuccess : LiveData<Event<Boolean>>
get() = _showSuccess
In the Fragment:
myViewModel.showSuccess.observe(viewLifecycleOwner, Observer {
it.getContentIfNotHandled()?.let {
// This is only executed if the event has never been handled
showSuccess(...)
}
})
Upvotes: 5