I was looking at the JetSurvey project (Android Jetpack Compose sample project) and noticed that they created a class to wrap the LiveData value in their ViewModel class. Here is the class I'm talking about:
/**
* Used as a wrapper for data that is exposed via a LiveData that represents an event.
*/
data 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, this is used like so:
private val _navigateTo = MutableLiveData<Event<Screen>>()
val navigateTo: LiveData<Event<Screen>> = _navigateTo
fun signInAsGuest() {
_navigateTo.value = Event(Survey)
}
It seems the point of the Event class is to avoid the navigation from happening multiple times. However, I don't understand how that would happen in the first place, because the navigation would only get triggered once the LiveData value is updated. And every time the value is updated, a new Event object is created, so it would run again.
So in the Fragment, is there a chance that the code inside viewModel.navigateTo.observe(viewLifecycleOwner)
can run multiple times without the value having been updated? If so, in what cases would that happen?
If my understanding of the role of the Event wrapper is incorrect, for what purpose is it being implemented? Is it necessary at all?