下面两个示例简单地将'a‘添加到给定的默认值中。所使用的compose_version是1.0.0-alpha03,这是最新的(据我所知)。
这个例子与我在研究中发现的大多数例子非常相似。
示例1
@Composable
fun MyScreen() {
val (name, setName) = remember { mutableStateOf("Ma") }
Column {
Text(text = name) // 'Ma'
Button(onClick = {
setName(name + "a") // change it to 'Maa'
}) {
Text(text = "Add an 'a'")
}
}
}然而,这并不总是切合实际的。例如,数据比单个字段更复杂。例如,一个类,甚至一个Room data class。
示例2
// the class to be modified
class MyThing(var name: String = "Ma");
@Composable
fun MyScreen() {
val (myThing, setMyThing) = remember { mutableStateOf(MyThing()) }
Column {
Text(text = myThing.name) // 'Ma'
Button(onClick = {
var nextMyThing = myThing
nextMyThing.name += "a" // change it to 'Maa'
setMyThing(nextMyThing)
}) {
Text(text = "Add an 'a'")
}
}
}当然,示例1可以工作,但是示例2不能工作。对于我来说,这是一个简单的错误,还是我忽略了应该如何修改这个类实例的更大的图景?
编辑:
我已经找到了一种方法来完成这个任务,但是它看起来效率很低。然而,它确实与React管理状态的方式相一致,因此它可能是正确的方法。
示例2中的问题非常清楚地是,myNextThing不是原始myThing的副本,而是对它的引用。就像React一样,Jetpack撰写在修改状态时似乎需要一个全新的对象。这可以通过以下两种方式之一实现:
MyThing类的新实例,更改需要更改的内容,然后使用新的类实例调用setMyThing()class MyThing更改为data class MyThing,并使用copy()函数创建具有相同属性的新实例。然后,更改所需的属性并调用setMyThing()。在我的问题中,这是最好的方法,因为我明确表示,我想用它来修改Android使用的给定data class上的数据。示例3 (函数式)
// the class to be modified
data class MyThing(var name: String = "Ma");
@Composable
fun MyScreen() {
val (myThing, setMyThing) = remember { mutableStateOf(MyThing()) }
Column {
Text(text = myThing.name) // 'Ma'
Button(onClick = {
var nextMyThing = myThing.copy() // make a copy instead of a reference
nextMyThing.name += "a" // change it to 'Maa'
setMyThing(nextMyThing)
}) {
Text(text = "Add an 'a'")
}
}
}发布于 2021-07-15 16:47:58
好的,对于任何想知道这个问题的人来说,有一个更简单的方法来解决这个问题。当您定义如下可变状态属性时:
//There is a second paremeter wich defines the policy of the changes on de state if you
//set this value to neverEqualPolicy() you can make changes and then just set the value
class Vm : ViewModel() {
val dummy = mutableStateOf(value = Dummy(), policy= neverEqualPolicy())
//Update the value like this
fun update(){
dummy.value.property = "New value"
//Here is the key since it has the never equal policy it will treat them as different no matter the changes
dummy.value = dummy.value
}
}有关可用策略的更多信息:https://developer.android.com/reference/kotlin/androidx/compose/runtime/SnapshotMutationPolicy
https://stackoverflow.com/questions/63956058
复制相似问题