Jetpack Compose State: Modify class property(Jetpack Compose State:修改类属性)
本文介绍了Jetpack Compose State:修改类属性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
以下两个示例仅将‘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不行。这是我的一个简单错误,还是我错过了应该如何修改这个类实例的大局?
编辑:
我找到了一种某种方法来实现此功能,但似乎效率不高。但是,它确实与Reaction管理状态的方式一致,因此这可能是正确的做法。
示例2中的问题非常清楚,myNextThing
不是原始myThing
的副本,而是对它的引用。就像Reaction一样,Jetpack Compose在修改状态时似乎需要一个全新的对象。这可以通过以下两种方式之一完成:
- 创建
MyThing
类的新实例,更改需要更改的内容,然后使用新的类实例调用setMyThing()
- 将
class MyThing
更改为data class MyThing
,并使用copy()
函数创建具有相同属性的新实例。然后,更改所需的属性并调用setMyThing()
。在我的问题上下文中,这是最好的方法,因为我明确表示,我希望使用此方法修改Android Room使用的给定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'")
}
}
}
推荐答案
确实,在我看来最好的方法是复制()一个数据类。
在使用自定义data class
的remember()
的特定情况下,这可能确实是最好的选择,不过通过在copy()
函数上使用命名参数可以更简洁地完成此操作:
// the class to be modified
data class MyThing(var name: String = "Ma", var age: Int = 0)
@Composable
fun MyScreen() {
val (myThing, myThingSetter) = remember { mutableStateOf(MyThing()) }
Column {
Text(text = myThing.name)
// button to add "a" to the end of the name
Button(onClick = { myThingSetter(myThing.copy(name = myThing.name + "a")) }) {
Text(text = "Add an 'a'")
}
// button to increment the new "age" field by 1
Button(onClick = { myThingSetter(myThing.copy(age = myThing.age + 1)) }) {
Text(text = "Increment age")
}
}
}
但是,我们仍将更新视图模型并观察它们的结果(LiveData
、StateFlow
、RxJavaObservable
等)。我希望remember { mutableStateOf() }
将在本地用于尚未准备好提交到视图模型但需要多位用户输入的数据,因此需要将其表示为状态。您是否觉得需要data class
由您决定。
这是我的一个简单错误,还是我错过了应该如何修改此类实例的大问题?
Compose无法知道对象已更改,因此它不知道需要重新组合。
总体而言,Compose是围绕对不可变数据流的反应而设计的。remember { mutableStateOf() }
创建本地流。
不过,我们非常欢迎另一种方法。
您不限于单个remember
:
@Composable
fun MyScreen() {
val name = remember { mutableStateOf("Ma") }
val age = remember { mutableStateOf(0) }
Column {
Text(text = name.value)
// button to add "a" to the end of the name
Button(onClick = { name.value = name.value + "a"}) {
Text(text = "Add an 'a'")
}
// button to increment the new "age" field by 1
Button(onClick = { age.value = age.value + 1 }) {
Text(text = "Increment age")
}
}
}
这篇关于Jetpack Compose State:修改类属性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
沃梦达教程
本文标题为:Jetpack Compose State:修改类属性


猜你喜欢
- Android - 我如何找出用户有多少未读电子邮件? 2022-01-01
- Android - 拆分 Drawable 2022-01-01
- 使用自定义动画时在 iOS9 上忽略 edgesForExtendedLayout 2022-01-01
- 用 Swift 实现 UITextFieldDelegate 2022-01-01
- MalformedJsonException:在第1行第1列路径中使用JsonReader.setLenient(True)接受格式错误的JSON 2022-01-01
- android 4中的android RadioButton问题 2022-01-01
- 在测试浓缩咖啡时,Android设备不会在屏幕上启动活动 2022-01-01
- Android viewpager检测滑动超出范围 2022-01-01
- 想使用ViewPager,无法识别android.support.*? 2022-01-01
- 如何检查发送到 Android 应用程序的 Firebase 消息的传递状态? 2022-01-01