【发布时间】:2021-12-07 09:12:49
【问题描述】:
我正在做实验以理解重组和智能重组并制作了一个样本
对不起颜色,它们是用 Random.nextIn() 生成的,可以直观地观察重组,设置颜色对重组没有影响,也尝试过不改变颜色。
gif中的内容由三部分组成
样本1
@Composable
private fun Sample1() {
Column(
modifier = Modifier
.background(getRandomColor())
.fillMaxWidth()
.padding(4.dp)
) {
var counter by remember { mutableStateOf(0) }
Text("Sample1", color = getRandomColor())
Button(
modifier = Modifier
.fillMaxWidth()
.padding(vertical = 4.dp),
colors = ButtonDefaults.buttonColors(backgroundColor = getRandomColor()),
onClick = {
counter++
}) {
Text("Counter: $counter", color = getRandomColor())
}
}
}
我在这里没有问题,因为智能合成按预期工作,顶部的Text 没有读取counter 中的更改,因此仅在Button 内的Text 发生重组。
样本2
@Composable
private fun Sample2() {
Column(
modifier = Modifier.background(getRandomColor())
) {
var update1 by remember { mutableStateOf(0) }
var update2 by remember { mutableStateOf(0) }
println("ROOT")
Text("Sample2", color = getRandomColor())
Button(
modifier = Modifier
.padding(start = 8.dp, end = 8.dp, top = 4.dp)
.fillMaxWidth(),
colors = ButtonDefaults.buttonColors(backgroundColor = getRandomColor()),
onClick = {
update1++
},
shape = RoundedCornerShape(5.dp)
) {
println("???? Button1️")
Text(
text = "Update1: $update1",
textAlign = TextAlign.Center,
color = getRandomColor()
)
}
Button(
modifier = Modifier
.padding(start = 8.dp, end = 8.dp, top = 2.dp)
.fillMaxWidth(),
colors = ButtonDefaults.buttonColors(backgroundColor = getRandomColor()),
onClick = { update2++ },
shape = RoundedCornerShape(5.dp)
) {
println("???? Button 2️")
Text(
text = "Update2: $update2",
textAlign = TextAlign.Center,
color = getRandomColor()
)
}
Column(
modifier = Modifier.background(getRandomColor())
) {
println("???? Inner Column")
var update3 by remember { mutableStateOf(0) }
Button(
modifier = Modifier
.padding(start = 8.dp, end = 8.dp, top = 2.dp)
.fillMaxWidth(),
colors = ButtonDefaults.buttonColors(backgroundColor = getRandomColor()),
onClick = { update3++ },
shape = RoundedCornerShape(5.dp)
) {
println("✅ Button 3️")
Text(
text = "Update2: $update2, Update3: $update3",
textAlign = TextAlign.Center,
color = getRandomColor()
)
}
}
Column() {
println("☕️ Bottom Column")
Text(
text = "Sample2",
textAlign = TextAlign.Center,
color = getRandomColor()
)
}
}
}
它也可以按预期工作,每个 mutableState 仅更新它们被观察到的范围。当这些 mutableState 中的任何一个被更新时,只有观察到 update2 和 update3 的 Text 会发生变化。
样本3
@Composable
private fun Sample3() {
Column(
modifier = Modifier.background(getRandomColor())
) {
var update1 by remember { mutableStateOf(0) }
var update2 by remember { mutableStateOf(0) }
println("ROOT")
Text("Sample3", color = getRandomColor())
Button(
modifier = Modifier
.padding(start = 8.dp, end = 8.dp, top = 4.dp)
.fillMaxWidth(),
colors = ButtonDefaults.buttonColors(backgroundColor = getRandomColor()),
onClick = {
update1++
},
shape = RoundedCornerShape(5.dp)
) {
println("???? Button1️")
Text(
text = "Update1: $update1",
textAlign = TextAlign.Center,
color = getRandomColor()
)
}
Button(
modifier = Modifier
.padding(start = 8.dp, end = 8.dp, top = 2.dp)
.fillMaxWidth(),
colors = ButtonDefaults.buttonColors(backgroundColor = getRandomColor()),
onClick = { update2++ },
shape = RoundedCornerShape(5.dp)
) {
println("???? Button 2️")
Text(
text = "Update2: $update2",
textAlign = TextAlign.Center,
color = getRandomColor()
)
}
Column {
println("???? Inner Column")
var update3 by remember { mutableStateOf(0) }
Button(
modifier = Modifier
.padding(start = 8.dp, end = 8.dp, top = 2.dp)
.fillMaxWidth(),
colors = ButtonDefaults.buttonColors(backgroundColor = getRandomColor()),
onClick = { update3++ },
shape = RoundedCornerShape(5.dp)
) {
println("✅ Button 3️")
Text(
text = "Update2: $update2, Update3: $update3",
textAlign = TextAlign.Center,
color = getRandomColor()
)
}
}
// ???????? Reading update1 causes entire composable to recompose
Column(
modifier = Modifier.background(getRandomColor())
) {
println("☕️ Bottom Column")
Text(
text = "Update1: $update1",
textAlign = TextAlign.Center,
color = getRandomColor()
)
}
}
}
Sample2 和 Sample3 之间的唯一区别是底部的 Text 正在读取 update1 mutableState ,这会导致整个组合被重组。正如您在 gif 中看到的,更改 update1 会重构或更改 Sample3 的整个颜色模式。
重组整个可组合的原因是什么?
Column(
modifier = Modifier.background(getRandomColor())
) {
println("☕️ Bottom Column")
Text(
text = "Update1: $update1",
textAlign = TextAlign.Center,
color = getRandomColor()
)
}
}
【问题讨论】:
-
请问您如何测试在一段代码中发生的重组?是否有任何工具或只有日志?
-
在我发布的答案的文章中,有一个带有
SideEffect的日志代码,您可以计算重组次数。您可以使用 assertEquals 检查测试中的数字是否符合预期。
标签: android kotlin android-jetpack-compose