我可以在 ViewModel 中创建 MutableState 属性,但在 Android Jetpack Compose 中将它们公开为不可变的屏幕吗?

blo*_*let 2 mobile android mvvm kotlin android-jetpack-compose

在我的 ViewModel 中,我有一些属性MutableState,我只想.value在 ViewModel 内部更改它们,而不是在屏幕中更改它们。

通过具有这样的两个属性可以很容易地解决这个问题

private val _someScreenState = mutableStateOf("something")
val someScreenState: State<String> = _someScreenState
Run Code Online (Sandbox Code Playgroud)

但是,当拥有大量属性时,这会变得令人讨厌并且难以使用。那么有没有一种方法可以做同样的事情,但不必实例化两个State属性呢?

我知道 kotlin 有一种很好的方法来为类内的属性编写 getter 和 setter,例如像这样

var someScreenState = mutableStateOf("something")
    private set()
Run Code Online (Sandbox Code Playgroud)

这可以解决问题,因为属性本​​身是var(可变的),同时具有私有设置器。但是对于 compose,State我并不是试图更改属性本身,而是更改它的someScreenState.value属性,因此您仍然可以someScreenState.value在 ViewModel 之外进行更改。

我使用了像类这样的状态对象,ScreenState它保存了内部的所有State属性,但是很多属性必须是类型StateFlow,并且对于状态对象,您无法选择哪个是State哪个是StateFlow(状态对象还有其他问题)这也是我一直试图远离他们的原因)。

Abh*_*bhi 5

使用新的实验性 Kotlin 支持属性更改可以实现这一点。此功能需要 Kotlin 1.7、新的 K2 编译器以及一些更改才能启用它。

事情会是这样的。
(这可能不是确切的语法,因为它是实验性的,因为很长一段时间以来已经有很多讨论了)

在此输入图像描述

相关文章
https://nikoladespotoski.medium.com/overriding-backing-property-type-in ​​-kotlin-1-7-5581cd30e77a

完整讨论参考的相关 GitHub 问题,
https://github.com/Kotlin/KEEP/issues/278

YouTrack 问题链接
https://youtrack.jetbrains.com/issue/KT-14663