What is the most recommended approach to execute custom logic when setting value of MutableLiveData
?
I have a ViewModel
with several properties isConnecting
and isConnected
.
I want to set isConnecting
to false
when isConected
is changed
class MyViewModel : ViewModel() {
private var _isConnecting = MutableLiveData<Boolean>()
val isConnecting: LiveData<Boolean>
get () = _isConnecting
private var _isConnected = MutableLiveData<Boolean>()
val isConnected: LiveData<Boolean>
get () = _isConnected
}
One way to do it is creating a function inside MyViewModel
and set both properties:
fun setConnected(value: Boolean) {
_isConnected.value = value
_isConnecting.value = false
}
This is okay, but one must never set _isConnected
manually and always use function setConnected()
. It can not be guaranteed and thus there may be bugs.
Another way to do it is to make MyViewModel
observe its own MutableLiveData
:
class MyViewModel : ViewModel() {
// ...
private val isConnectedObserver = Observer<Boolean> {
_isConnecting.value = false
}
init {
isConnected.observeForever(isConnectedObserver)
}
override fun onCleared() {
super.onCleared()
isConnected.removeObserver(isConnectedObserver)
}
}
This avoids problem of first approach, but is just awful.
But is there a better way? For example using setters somehow?
Use MediatorLiveData
to observe other LiveData
objects and react on onChanged events from them:
class MyViewModel : ViewModel() {
private var _isConnecting = MediatorLiveData<Boolean>().also { liveData ->
liveData.addSource(_isConnected) { connected ->
// isConnected changed, some logic here
if (connected) {
liveData.value = false
}
}
}
val isConnecting: LiveData<Boolean>
get() = _isConnecting
private var _isConnected = MutableLiveData<Boolean>()
val isConnected: LiveData<Boolean>
get() = _isConnected
}