我想我在这里遗漏了Jetpack Compose的一个核心概念。当我试图更改一个可组合对象中的non-constructor
data class
property
时遇到了一个问题,而这个可组合对象是观察列表的一部分。
不工作:(建构函式中未宣告sadProperty
)
data class IntWrapper(val actualInt: Int = 0) {
var sadProperty: Int = 0
}
@Preview
@Composable
fun test() {
var state by remember { mutableStateOf(listOf(IntWrapper(1), IntWrapper(2), IntWrapper(3),IntWrapper(4)))}
fun onClick(item: IntWrapper) {
val indexOf = state.indexOf(item)
val newState = state.minus(item).toMutableList()
val copy = item.copy()
copy.sadProperty = Random.nextInt()
newState.add(indexOf, copy)
state = newState
}
Column() {
for (item in state) {
Text("ac: ${item.actualInt} sad: ${item.sadProperty}", modifier = Modifier.clickable { onClick(item)})
}
}
}
Works:(actualInt
在构造函数中声明)
data class IntWrapper(var actualInt: Int = 0) {
var sadProperty: Int = 0
}
@Preview
@Composable
fun test() {
var state by remember { mutableStateOf(listOf(IntWrapper(1), IntWrapper(2), IntWrapper(3),IntWrapper(4)))}
fun onClick(item: IntWrapper) {
val indexOf = state.indexOf(item)
val newState = state.minus(item).toMutableList()
val copy = item.copy()
copy.actualInt = Random.nextInt()
newState.add(indexOf, copy)
state = newState
}
Column() {
for (item in state) {
Text("ac: ${item.actualInt} sad: ${item.sadProperty}", modifier = Modifier.clickable { onClick(item)})
}
}
}
有人能解释一下为什么会这样吗?
2条答案
按热度按时间y53ybaqx1#
这看起来像是一个既有
Jetpack Compose
又有关于Kotlin
数据类的问题,跟我说说,我会尽力的。让我们先从Kotlin的数据类开始
按kotlin docs约
Data Class
编译器会自动从主要建构函式中宣告的所有属性衍生下列成员:
您的
IntWrapper
数据类有一个主构造函数、类名后面的括号,其中声明了1个属性。我们可以说,
IntWrapper
数据类actualInt
)IntWrapper(actualInt=?)
的toString()copy()
函数并且再次基于docs:
编译器只使用在自动生成的函数的主构造函数中定义的属性。要从生成的实现中排除属性,请在类体中声明它:
equals
将只使用/计算从IntWrapper's
主构造函数(即actualInt : Int
)声明的属性,并且sadProperty
被排除在外,因为它在数据类主体的一部分中。现在考虑以下内容:
它打印,
因为
equality
看到两个导出属性具有相同的值5
,所以sadProperty
被排除在该比较之外。印刷品,
因为生成的equals验证了生成的组件(
actualInt
)与两个IntWrapper
示例不相同。现在转到
Jetpack Compose
,应用我们对数据类所了解的一切,test
符合关于data class
的一切,它创建了一个带有新值的新对象,这就是Compose
触发re-composition
所需要的。test
将不会触发re-composition
,Compose
仍会看到相同的IntWrapper
示例,因为sadProperty
不是数据类的equals操作将使用的生成组件的一部分。wooyq4lh2#
在构成中,您必须使用下列两种方法之一来成功执行重组作业:
1 -使用mutableStateListOf(),但是,通过更新列表中项的值,执行重组操作
2-用你自己的方法
但是对于第二个方法,您需要告诉Compose actualInt已经更改,因此您需要创建一个新的int示例。
如果您不想这样做,则需要详细说明您的方案,以便我可以提供更完整的指南