An observable that triggers recomposition when it changes.
Stores states through composition and recomposition.
var name by remember { mutableStateOf("") }
Retains state like remember, but also through configuration changes. The saved state must be data type that can be added to the Bundle, such as Parcelized data class or implemented with either MapSaver or ListSaver
var name by rememberSavable { mutableStateOf("") }
remember scope
Avoid modifying state outside remember scope.
@Composable
fun HelloScreen() {
var name by rememberSaveable { mutableStateOf("") }
HelloContent(name = name, onNameChange = { name = it })
}
@Composable
fun HelloContent(name: String, onNameChange: (String) -> Unit) {
Column(modifier = Modifier.padding(16.dp)) {
Text(
text = "Hello, $name",
modifier = Modifier.padding(bottom = 8.dp),
style = MaterialTheme.typography.bodyMedium
)
OutlinedTextField(value = name, onValueChange = onNameChange, label = { Text("Name") })
}
}
Stateless : composable function without internal state.
Solution | Responsibilities |
---|---|
Composables | Simple UI-element state management |
State holder | Complex UI-element state management |
ViewModel | State holder for accessing business logic + screen state |
If benefits of ViewModel does not apply to the use case, plain state holders can also take ViewModel's responsibility.
Plain class which holds states for the UI elements and contains UI-related logics.
ViewModel as state holder can hoist state out of the composition since it has longer lifespan.
Should not take state created in composables since ViewModel lives longer than UI elements.