在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> = _countfun increment() {_count.value++}
}@Composable
fun CounterScreen(viewModel: CounterViewModel = viewModel()) {val count by viewModel.countButton(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> = _statefun 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或類似解決方案。