在我的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
(可变的),同时有一个私有的setter.但是对于compose的State
,我并不想改变属性本身,而是改变它的someScreenState.value
属性,所以你仍然可以在ViewModel之外改变someScreenState.value
.
我已经使用了状态对象,比如ScreenState
类,它包含了所有的State
属性,但是很多属性必须是StateFlow
类型,对于状态对象,你不能挑选哪个是State
,哪个是StateFlow
(状态对象还有其他问题,这就是为什么我一直试图远离它们)。
2条答案
按热度按时间h22fl7wq1#
这可以通过对Kotlin支持属性进行新的实验性修改来实现,该特性需要Kotlin 1.7,一个新的K2编译器,以及一些修改来启用它。
应该是这样的。
(This可能不是确切的语法,因为它是实验性的,因为围绕这一点已经有很多讨论很长时间了)
相关文章
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
hjzp0vay2#
你可以这样写:
注意,我在这里使用的是kotlin委托,您将获得类型
String
而不是MutableState<String>
,将其与private set
组合,现在您的对象为var
,您可以直接在视图模型中设置它,并且它在可组合对象中将是不可变的。而且你仍然可以用这种方式观察state
的变化。我认为它使用起来也更干净,因为你可以在没有.value
的情况下直接访问值但是,值得一提的是,
by
委托仅适用于组合State
,而不适用于StateFlow
视图模型:
可组合:
结果:
如您所见,我能够观察文本字段值的更改,这些更改成功地反映在可组合