五分钟快速了解 Jetpack Compose 状态管理

177 阅读1分钟

在 Jetpack Compose 中,State(状态)是 UI 响应式更新的核心。Compose 提供了多种 State 管理方式,主要包括以下几种:


1️⃣ remember:临时状态

  • 适用场景:存储 UI 生命周期内的可变状态,不会在重组中丢失,但不会跨配置变更(如屏幕旋转)。
  • 使用方式
val count = remember { mutableStateOf(0) }
Button(onClick = { count.value++ }) {
    Text("Count: ${count.value}")
}
  • 等价于
var count by remember { mutableStateOf(0) }

2️⃣ rememberSaveable:跨配置变更的状态

  • 适用场景:与 remember 类似,但它能在配置更改(如屏幕旋转)后保持状态
  • 使用方式
var text by rememberSaveable { mutableStateOf("") }
TextField(value = text, onValueChange = { text = it })
  • 底层机制:使用 SavedInstanceState 进行存储。

3️⃣ mutableStateOf:单一值状态

  • 适用场景:用于简单的数据存储,会触发 UI 重组。
  • 使用方式
val isChecked = remember { mutableStateOf(false) }
Checkbox(checked = isChecked.value, onCheckedChange = { isChecked.value = it })

4️⃣ derivedStateOf:避免不必要的重组

  • 适用场景:当 State 依赖于另一个 State 计算时,避免在每次 recomposition 重新计算。
  • 使用方式
val list = remember { mutableStateOf(listOf(1, 2, 3, 4, 5)) }
val evenNumbers by remember { derivedStateOf { list.value.filter { it % 2 == 0 } } }
  • 作用evenNumbers 只有在 list 变化时才会重新计算,而不会在 UI 重组时重新计算。

5️⃣ produceState:将 Flow/异步数据转换为 State

  • 适用场景:将 Flowsuspend function 结果转换成 State,适用于网络请求、数据库查询等异步数据。
  • 使用方式
val timeState = produceState(initialValue = 0) {
    while (true) {
        delay(1000)
        value++
    }
}
Text("Seconds: ${timeState.value}")

6️⃣ snapshotFlow:监听 State 变化并转为 Flow

  • 适用场景:将 Compose State 转换为 Flow 进行监听,适用于与协程结合的数据流操作。
  • 使用方式
val count = remember { mutableStateOf(0) }
LaunchedEffect(Unit) {
    snapshotFlow { count.value }
        .collect { println("Count changed to $it") }
}

7️⃣ collectAsState:从 Flow 获取 State

  • 适用场景:从 Flow 获取 UI 状态并更新 Compose 界面,适用于 ViewModel 处理数据流。
  • 使用方式
val viewModel: MyViewModel = viewModel()
val uiState by viewModel.uiStateFlow.collectAsState()
  • 底层机制:会自动取消订阅 Flow 并在 Composed 组件销毁时停止收集。

8️⃣ LaunchedEffect:副作用处理

  • 适用场景:执行只需运行一次的副作用,比如网络请求、数据库读取。
  • 使用方式
LaunchedEffect(Unit) {
    delay(2000)
    println("This runs once when the composition enters")
}

9️⃣ rememberCoroutineScope:管理 CoroutineScope

  • 适用场景:在 Composable 中启动协程,不会因为重组而重新创建协程作用域。
  • 使用方式
val coroutineScope = rememberCoroutineScope()
Button(onClick = {
    coroutineScope.launch {
        delay(1000)
        println("Coroutine executed")
    }
}) {
    Text("Start Task")
}

🔟 rememberUpdatedState:获取最新的 State

  • 适用场景:在 LaunchedEffectSideEffect 内,避免 State 过时的问题。
  • 使用方式
val latestValue = rememberUpdatedState(newValue)
LaunchedEffect(Unit) {
    delay(3000)
    println("Latest value: ${latestValue.value}") // 确保始终获取最新值
}

总结

状态管理方式适用场景
rememberUI 生命周期内的临时状态
rememberSaveable可在屏幕旋转等配置变更后保持状态
mutableStateOf监听单个变量的状态变化
derivedStateOf依赖另一个状态计算,避免不必要的重组
produceStatesuspend functionFlowState
snapshotFlowStateFlow
collectAsStateFlowState
LaunchedEffect副作用处理(如网络请求)
rememberCoroutineScope处理 CoroutineScope
rememberUpdatedState确保 State 始终保持最新