I am following the google android project "guess it" through udacity where they introduce livedata and mutablelivedata. We've got to the point where we're creating a livedata equivalent to a mutablelivedata object and creating a get() backingproperty for the livedata to the mutablelivedata instance. We make all changes to the data in the viewModel using the mutablelivedata instance. Our UI Fragment sets observers on the viewModel's livedata objects, NOT the mutablelivedata objects.
Dispite the observer being on the livedata instance and not the mutablelivedata instance, when the mutablelivedata object is updated, the livedata observer code is being triggered. I love that it works like this but I don't exactly understand how it works. Can anyone explain this to me?
In ViewModel
val _word = MutableLiveData<String>()
val word : LiveData<String>
get() = _word
Edit in ViewModel
private fun nextWord() {
//Select and remove a word from the list
if (wordList.isEmpty()) {
//gameFinished()
} else {
_word.value = wordList.removeAt(0)
}
}
In UI Fragment
viewModel.word.observe(this, Observer{newWord ->
binding.wordText.text = newWord
})
Our UI Fragment sets observers on the viewModel's livedata objects, NOT the mutablelivedata objects.
It is the same object. _word
and word
both point to the MutableLiveData
. However, from a data type standpoint, word
is defined as a LiveData
, to hide the implementation details from the fragment.
So, the observers are being placed on the same object that is getting the value updates.
Personally, I prefer to write this code as:
private val _word = MutableLiveData<String>()
val word : LiveData<String> = _word
...as IMHO that is easier to read and has the same effect.