从 ViewModel 暴露状态
使用 ViewModel 驱动 Compose 用户界面
从 ViewModel 暴露状态 是 CoddyKit 上的免费 Android Academy 课时。 这是第 2 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 Android Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 Android Academy 课程共包含 4 节课。
向 UI 暴露状态
ViewModel 负责保存状态,但 UI 需要一种观察状态的方式,以便在状态变化时重新渲染。
在现代 Android 中,常用的两种工具是:StateFlow 和 Compose State。
可变与不可变模式
最佳实践是保留一个私有可变的后备属性,同时暴露一个公共只读版本。
这样可以防止 UI 意外直接修改状态。
使用 StateFlow 暴露状态
在内部使用 MutableStateFlow,并将其以只读 StateFlow 的形式暴露。
class CounterViewModel : ViewModel() {
private val _count = MutableStateFlow(0)
val count: StateFlow<Int> = _count.asStateFlow()
fun increment() {
_count.value++
}
}在 Compose 中收集 StateFlow
Composable 使用 collectAsState()(或稍后介绍的生命周期感知变体)将流转换为 Compose 状态。
@Composable
fun CounterScreen(vm: CounterViewModel) {
val count by vm.count.collectAsState()
Text("Count: " + count)
}StateFlow 为什么需要初始值
StateFlow 始终具有当前值。因此,创建它时必须提供初始值。
任何新的收集者都会立即收到最新值,而不会得到空流。
替代方案:Compose mutableStateOf
对于 ViewModel 中简单的屏幕局部状态,您也可以使用 Compose 的 mutableStateOf,Compose 会自动观察它。
class CounterViewModel : ViewModel() {
var count by mutableStateOf(0)
private set
fun increment() { count++ }
}StateFlow 与 Compose State
- StateFlow 是 Kotlin 协程的一部分,可以在任何地方使用,而不仅限于 Compose。它非常适合共享且具备生命周期感知能力的流。
- mutableStateOf 专用于 Compose,写法十分简洁。
在大型应用中,ViewModel 通常更推荐使用 StateFlow。
将屏幕状态建模为一个对象
不要使用许多相互独立的流,而应将相关字段组合到一个 UI 状态数据类中。这样可以让更新保持原子性并且更可预测。
data class ProfileUiState(
val name: String = "",
val isLoading: Boolean = false,
val error: String? = null
)暴露 UI 状态对象
暴露一个由该状态类构成的 StateFlow。UI 可以从单一事实来源读取所有内容。
private val _uiState = MutableStateFlow(ProfileUiState())
val uiState: StateFlow<ProfileUiState> =
_uiState.asStateFlow()更新不可变状态
请通过生成包含已更改字段的 copy 来更新状态,而不要修改旧对象。
fun load() {
_uiState.update { it.copy(isLoading = true) }
// ... fetch, then:
_uiState.update {
it.copy(isLoading = false, name = "Ada")
}
}事件向上流动,状态向下流动
这就是单向数据流的核心:
- 状态从 ViewModel 向下流向界面。
- 事件通过函数调用从界面向上流向 ViewModel。
快速检查
请测试您对暴露状态的理解。
回顾
您学到了:
- 保留一个私有的
MutableStateFlow,并暴露只读的StateFlow。 - 将相关字段归组到界面状态数据类中。
- 通过
update {}使用copy()进行更新。 - 状态向下流动,事件向上流动。
常见问题解答
「从 ViewModel 暴露状态」课时是免费的吗?
是的 — 「从 ViewModel 暴露状态」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 Android Academy 课程的其余内容,请升级到 CoddyKit PRO。 Android Academy 课程共包含 4 节课。
「从 ViewModel 暴露状态」这节课中我会学到什么?
使用 ViewModel 驱动 Compose 用户界面 你通过在浏览器中直接运行的动手代码来练习 Android Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。
学习 Android Academy 需要有经验吗?
无需任何先前经验。CoddyKit 上的 Android Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 2 节课,共 4 节。
「从 ViewModel 暴露状态」课时需要多长时间?
大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。
我能在这节 Android Academy 课中编写并运行代码吗?
能。每节 Android Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。
此课程中的所有课时
- 为什么使用 ViewModel
- 从 ViewModel 暴露状态
- Android 生命周期
- collectAsStateWithLifecycle