首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Jetpack组合状态:修改类属性

Jetpack组合状态:修改类属性
EN

Stack Overflow用户
提问于 2020-09-18 12:46:07
回答 4查看 8.7K关注 0票数 16

下面两个示例简单地将'a‘添加到给定的默认值中。所使用的compose_version1.0.0-alpha03,这是最新的(据我所知)。

这个例子与我在研究中发现的大多数例子非常相似。

示例1

代码语言:javascript
运行
复制
@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

代码语言:javascript
运行
复制
// 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撰写在修改状态时似乎需要一个全新的对象。这可以通过以下两种方式之一实现:

  1. 创建MyThing类的新实例,更改需要更改的内容,然后使用新的类实例调用setMyThing()
  2. class MyThing更改为data class MyThing,并使用copy()函数创建具有相同属性的新实例。然后,更改所需的属性并调用setMyThing()。在我的问题中,这是最好的方法,因为我明确表示,我想用它来修改Android使用的给定data class上的数据。

示例3 (函数式)

代码语言:javascript
运行
复制
// 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'")
        }
    }
}
EN

Stack Overflow用户

发布于 2021-07-15 16:47:58

好的,对于任何想知道这个问题的人来说,有一个更简单的方法来解决这个问题。当您定义如下可变状态属性时:

代码语言:javascript
运行
复制
//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

票数 10
EN
查看全部 4 条回答
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/63956058

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档