视图模型中的 MutableState?

Luc*_*ann 21 android-jetpack-compose

在我看到的视图模型与 Jetpack Compose 结合使用的所有示例中,通常将视图模型中的状态存储为 MutableStateFlow,然后在 compose 函数中应用collectAsState 以获得 Compose 状态。

我的问题:为什么不直接将状态存储在视图模型中,而不是一些流程?例如

class MyViewModel: ViewModel() {
    val showDialog = mutableStateOf(false)
}

@Compose
fun MyScreen(viewModel: MyViewModel) {
    Button(onClick = { viewModel.showDialog = true })
    if (viewModel.showDialog) {
        AlertDialog(...)
    }
}
Run Code Online (Sandbox Code Playgroud)

上面的代码似乎按预期运行。那么这是一个有效的解决方案吗?

Ric*_*per 20

是的,确实如此。我不知道你在哪里看到这些例子,但这确实是推荐的做法。您可以查看StateCodelab;它演示了如何将LiveData对象替换mutableStateOfviewmodel. 另外,就LiveDataand的用法Flow而言,据我所知,主要是为了互操作性。未完全内置于 Compose 中但正在转移的应用程序,或计划与 Compose 一起使用视图系统的应用程序。mutableStateOf仅适用于 Jetpack compose,因此开发人员希望LiveData在这种情况下使用。但是,如果您正在构建一个全新的项目,并且希望它仅由 Compose 组成,那么一定要遵循您在问题中提到的内容。这是正确的方法。

  • 万分感谢!根据您的建议,我设法在 Codelab 中找到了它。然而,在文档(例如https://developer.android.com/jetpack/compose/state#viewmodel-state)中似乎没有提到这一点。 (2认同)
  • 我见过人们在使用 liveData 进行重组时遇到问题,而使用可变状态进行简单交换就可以解决问题。它是专门为撰写而构建的,我认为这绝对是推荐的做法。另外,我不知道该文档,但在我见过的其他地方(在其他文档中),mutableStateOf 是 Compose 的最佳实现。我认为 Codelab 也是由这些文档的作者编写的。 (2认同)
  • 理论上,ViewModel 不应该知道 UI 的实现细节,也不应该依赖于包 _androidx.compose_ 中给出的类。否则,每当您更改 UI 框架时,您都必须修改 ViewModel。但也许我太挑剔了。 (2认同)

And*_* H. 10

mutableStateOf()在视图模型中使用是可行的,但这不再是最好的方法。

\n

如果您查看最新版本的官方文档,包括 Now in Android 参考应用程序,视图模型应该保持以数据为中心,因此使用以数据为中心MutableStateFlow而不是以 Compose 为中心mutableStateOf()

\n

Android 开发者指南 \xe2\x80\x93\xc2\xa0Foundation:屏幕 UI 状态

\n

Android 开发人员指南 \xe2\x80\x93\xc2\xa0App 架构:从后台线程改变 UI 状态

\n

现在在Android \xe2\x80\x93\xc2\xa0查看模型

\n

现在在 Android 中 - 屏幕

\n

从单元测试的角度来看,使用MutableStateFlow也更有意义。当单独测试视图模型时,对 Compose(或其他以 UI 为中心的包和类)的任何依赖都应该是一个危险信号。换句话说,为什么在测试视图模型时需要任何 Compose 依赖项?

\n

  • 您的 2 个链接返回 404。您能否引用链接中关于为什么在 ViewModel 中使用状态不好的确切位置?mutableStateOf() 在测试中确实有效,那么为什么它是一个危险信号呢? (8认同)