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.
