Doing jetpack compose codelab(state), In ViewModel there's something Can't make sense I think.
And I'm so confused that have some questions. Here is codes from codelab
VieModel
class TodoViewModel : ViewModel() {
private var _todoItems = MutableLiveData(listOf<TodoItem>())
val todoItems: LiveData<List<TodoItem>> = _todoItems
// ...
}
First
Here is my thought.
todoItems
is variable that contains MutableLiveData which contains list of TodoItems.
And todoItems
is value that have type LiveData<List<TodoItem>>
and contain _todoItems
In this flow, why todoItems
has that type?
Why the first type from MutableLiveData(listOf<TodoItem>())
is equivalent to LiveData<List<TodoItem>>
?
Second
Second questions is about using that viewmodel with variable.
here is codes.
@Composable
private fun TodoActivityScreen(todoViewModel: TodoViewModel) {
val items: List<TodoItem> by todoViewModel.todoItems.observeAsState(listOf())
TodoScreen(
items = items,
onAddItem = { todoViewModel.addItem(it) },
onRemoveItem = { todoViewModel.removeItem(it) }
)
}
items
from ViewModel is just List<TodoItem>
.
And Why the type returned to List<TodoItem>
?
CodePudding user response:
For your first question,
We want to update the list of TodoItem
that's why we need a MutableLiveData
. But we don't want to expose this mutable property to outside world as no one outside view model should be able to modify this list. So we expose a LiveData
which is immutable. Since MutableLiveData
extends LiveData
we can directly assign _todoItems
to todoItems
.
For your second question,
observeAsState
is an extension function on LiveData
which converts it to a State
, in your case State<List<TodoItem>>
. by
is used to unwrap the State
and directly access the List<TodoItem
which is then supplied to TodoScreen
. Whenever the value of todoViewModel.todoItems
changes, items
will be initialised with new value and TodoActivityScreen
will get recomposed.