Lesson 17: Introduction to ViewModel
Introduction to ViewModel
A ViewModel holds UI-related data and survives configuration changes (like screen rotation) that would otherwise destroy and recreate your Activity, along with any plain remember-based state inside it.
Add the dependency
implementation("androidx.lifecycle:lifecycle-viewmodel-compose:2.8.0")A basic ViewModel
class TaskListViewModel : ViewModel() {
private val _tasks = mutableStateListOf(
Task(1, "Buy groceries"),
Task(2, "Finish report")
)
val tasks: List get() = _tasks
fun addTask(title: String) {
_tasks.add(Task(_tasks.size + 1, title))
}
}Using it in a composable
@Composable
fun TaskListScreen(viewModel: TaskListViewModel = viewModel()) {
LazyColumn {
items(viewModel.tasks) { task ->
Text(task.title, modifier = Modifier.padding(16.dp))
}
}
}viewModel() is a special composable function that either creates a new TaskListViewModel the first time, or hands you back the same instance if one already exists for this screen — including after a rotation. This is what actually solves the "data disappears on rotation" problem from lesson 7.
Why underscore-prefixed private properties?
Notice _tasks is private, with a public tasks exposing a read-only view. This is a deliberate pattern: the ViewModel controls all mutations (through functions like addTask), while the UI can only read the current data, never modify it directly. This keeps your data flow predictable — the UI reacts to state, it doesn't reach in and change it arbitrarily.
Next: Lesson 18 — the bigger architectural picture this pattern is part of.