Tic*_*ers 5 android kotlin data-class android-jetpack-compose compose-recomposition
我认为我在这里缺少 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)})
}
}
}
Run Code Online (Sandbox Code Playgroud)
作品:(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)})
}
}
}
Run Code Online (Sandbox Code Playgroud)
有人可以解释为什么会发生这种情况吗?
这看起来像是一个Jetpack Compose关于Kotlin数据类的问题,对我来说,我会尽力而为。
让我们首先从 Kotlin 的 Data 类开始
根据kotlin 文档关于Data Class
编译器自动从主构造函数中声明的所有属性派生以下成员:
- equals()/hashCode() 对
- toString() 形式为“User(name=John,age=42)”
- componentN() 函数对应于属性的声明顺序。
- 复制() 。
您的IntWrapper数据类有一个Primary Constructor、类名后面的括号,以及在其中声明的 1 个属性。
data class IntWrapper(val actualInt: Int = 0) {
var sadProperty: Int = 0
}
Run Code Online (Sandbox Code Playgroud)
这样,我们可以说,你的IntWrapper数据类有
actualInt)IntWrapper(actualInt=?)copy()函数并再次基于文档:
编译器仅使用主构造函数中定义的属性来自动生成函数。要从生成的实现中排除某个属性,请在类主体中声明它:
只会使用/评估从主构造函数(即)equals声明的属性,并且由于它位于数据类主体的一部分而被排除在外。IntWrapper'sactualInt : IntsadProperty
现在考虑以下事项:
val intWrapper1 = IntWrapper(actualInt = 5)
intWrapper1.sadProperty = 5
val intWrapper2 = IntWrapper(actualInt = 5)
intWrapper2.sadProperty = 10
Log.e("AreTheyEqual?", "${intWrapper1 == intWrapper2}")
Run Code Online (Sandbox Code Playgroud)
它打印,
E/AreTheyEqual?: true
Run Code Online (Sandbox Code Playgroud)
因为equality看到两个派生属性具有相同的值5,sadProperty所以被排除在此比较之外。
val intWrapper1 = IntWrapper(actualInt = 5)
intWrapper1.sadProperty = 5
val intWrapper2 = IntWrapper(actualInt = 10)
intWrapper2.sadProperty = 5
Run Code Online (Sandbox Code Playgroud)
印刷,
E/AreTheyEqual?: false
Run Code Online (Sandbox Code Playgroud)
因为生成的 equals 验证了两个实例中生成的组件 ( actualInt) 不相同IntWrapper。
现在,将Jetpack Compose我们所理解的一切应用到数据类中,
第一个test符合有关的所有内容data class,它创建一个具有新值的新对象,这就是Compose需要触发的内容re-composition。
第二个test不会触发re-composition,Compose仍然会看到相同的IntWrapper实例,因为sadProperty它不是数据类的 equals 操作将使用的生成组件的一部分。
| 归档时间: |
|
| 查看次数: |
1911 次 |
| 最近记录: |