在Jetpack Compose中,界面状态管理是构建响应式UI的核心。以下是Compose状态管理的主要概念和实现方式:
基本状态管理
1. 使用 mutableStateOf
@Composable
fun Counter() {
var count by remember { mutableStateOf(0) }
Button(onClick = { count++ }) {
Text("Clicked $count times")
}
}
2. 使用 remember
和 rememberSaveable
@Composable
fun LoginScreen() {
var username by rememberSaveable { mutableStateOf("") }
var password by rememberSaveable { mutableStateOf("") }
Column {
TextField(
value = username,
onValueChange = { username = it },
label = { Text("Username") }
)
TextField(
value = password,
onValueChange = { password = it },
label = { Text("Password") }
)
}
}
状态提升 (State Hoisting)
@Composable
fun StatefulCounter() {
var count by remember { mutableStateOf(0) }
StatelessCounter(count, { count++ })
}
@Composable
fun StatelessCounter(count: Int, onIncrement: () -> Unit) {
Button(onClick = onIncrement) {
Text("Clicked $count times")
}
}
ViewModel 集成
class CounterViewModel : ViewModel() {
private val _count = mutableStateOf(0)
val count: State<Int> = _count
fun increment() {
_count.value++
}
}
@Composable
fun CounterScreen(viewModel: CounterViewModel = viewModel()) {
val count by viewModel.count
Button(onClick = { viewModel.increment() }) {
Text("Clicked $count times")
}
}
复杂状态管理
1. 使用数据类管理多个状态
data class LoginState(
val username: String = "",
val password: String = "",
val isLoading: Boolean = false,
val error: String? = null
)
@Composable
fun LoginScreen() {
var state by remember { mutableStateOf(LoginState()) }
Column {
if (state.isLoading) {
CircularProgressIndicator()
}
TextField(
value = state.username,
onValueChange = { state = state.copy(username = it) }
)
TextField(
value = state.password,
onValueChange = { state = state.copy(password = it) }
)
state.error?.let {
Text(it, color = Color.Red)
}
}
}
2. 使用 StateFlow 和 ViewModel
class LoginViewModel : ViewModel() {
private val _state = MutableStateFlow(LoginState())
val state: StateFlow<LoginState> = _state
fun onUsernameChange(username: String) {
_state.update { it.copy(username = username) }
}
fun onPasswordChange(password: String) {
_state.update { it.copy(password = password) }
}
}
@Composable
fun LoginScreen(viewModel: LoginViewModel = viewModel()) {
val state by viewModel.state.collectAsState()
Column {
TextField(
value = state.username,
onValueChange = viewModel::onUsernameChange
)
TextField(
value = state.password,
onValueChange = viewModel::onPasswordChange
)
}
}
状态恢复 (State Restoration)
@Composable
fun RememberSaveableExample() {
var selectedTab by rememberSaveable { mutableStateOf(0) }
TabRow(selectedTabIndex = selectedTab) {
listOf("Tab 1", "Tab 2", "Tab 3").forEachIndexed { index, title ->
Tab(
selected = selectedTab == index,
onClick = { selectedTab = index },
text = { Text(title) }
)
}
}
}
最佳实践
- 单一数据源:确保每个状态只有一个可信来源
- 最小化状态:只存储必要的UI状态
- 状态提升:将状态提升到共享的父组件
- 不可变状态:使用copy或新实例来更新状态
- 分离业务逻辑:将复杂逻辑放在ViewModel或业务层
选择哪种状态管理方式取决于应用复杂度和团队偏好。对于简单组件,mutableStateOf
足够;对于复杂应用,建议使用ViewModel配合StateFlow或类似解决方案。