【问题标题】:Can I create MutableState properties in a ViewModel but expose them as immutable to screens in Android Jetpack Compose?我可以在 ViewModel 中创建 MutableState 属性,但在 Android Jetpack Compose 中将它们作为不可变属性公开给屏幕吗?
【发布时间】:2023-02-24 19:03:04
【问题描述】:

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

这很容易通过有两个像这样的属性来解决

private val _someScreenState = mutableStateOf("something")
val someScreenState: State<String> = _someScreenState

但是当有很多属性时,这会变得很烦人并且难以使用。那么有没有一种方法可以做同样的事情,而不必实例化两个State属性?

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

var someScreenState = mutableStateOf("something")
    private set()

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

我使用了像 ScreenState 类这样的状态对象,它在内部包含所有 State 属性,但是很多属性必须是 StateFlow 类型,并且对于状态对象你不能挑选哪个是 @987654333 @ 是 StateFlow(状态对象还有其他问题,这也是我一直试图摆脱它们的原因)。

【问题讨论】:

    标签: android kotlin mobile mvvm android-jetpack-compose


    【解决方案1】:

    你可以这样写:

    var state by mutableStateOf("something") //Type is String
        private set
    

    请注意,我在这里使用的是 kotlin 委托,您将输入 String 而不是 MutableState&lt;String&gt;,将其与 private set 组合,现在您的对象为 var,您可以直接在视图模型中设置它,并且它在您的可组合项中将是不可变的,并且您仍然可以通过这种方式观察 state 的变化。我认为它使用起来也更干净,因为您可以直接访问该值而无需 .value

    然而,值得一提的是,by delegation 仅适用于 compose MutableState,它不适用于 StateFlow

    【讨论】:

      猜你喜欢
      • 2022-07-27
      • 2018-04-21
      • 2013-04-03
      • 2019-02-20
      • 1970-01-01
      • 2020-04-28
      • 1970-01-01
      • 2011-01-02
      • 2015-10-26
      相关资源
      最近更新 更多