0Pricing
Android Academy · 课时

从 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 反馈 — 无需本地设置。

此课程中的所有课时

  1. 为什么使用 ViewModel
  2. 从 ViewModel 暴露状态
  3. Android 生命周期
  4. collectAsStateWithLifecycle
← 返回 Android Academy