nim*_*ima 8 kotlin android-jetpack-compose compose-desktop
我有一个TextField用于搜索查询和一个Button将执行搜索的查询,结果显示在列中。由于搜索需要几秒钟才能运行,我希望它在按下按钮时执行,而不是在文本更改时执行。
这是一个简化的演示:
Column {
val list = remember { mutableStateListOf<String>() }
val textFieldValue = remember { mutableStateOf(TextFieldValue("")) }
TextField(
value = textFieldValue.value,
onValueChange = { textFieldValue.value = it }
)
Button({
list.clear()
list.addAll(textFieldValue.value.text.split(""))
}) {
Text("Search")
}
list.forEach {
println("test")
Text(it)
}
}
Run Code Online (Sandbox Code Playgroud)
第一次按下按钮后,foreach 循环将在文本更改时运行。即使单击TextField也会重新运行循环。这不会在文本更改时运行搜索,而是重新呈现结果,这会导致在文本字段中输入时出现故障。
如何防止这种情况发生?
Phi*_*hov 13
上述情况对于 Jetpack Compose 来说是正确的。作者想了解 Compose Desktop,但目前还不太一样,因为它还处于 alpha 阶段,还没有进行太多优化。
修改一个mutableState值总是会导致所有视图的重组,即其读取值。
Any changes to value will schedule recomposition of any composable functions that read value. 文档
阻止它的方法是将所有读取mutableState值的视图移出到单独的视图中。每次值更改都会重新组合mutableState,但不会影响容器。
在您的情况下,这非常简单:只需移动TextField并传递textFieldValue到新函数即可。您可以转发您需要的所有参数,例如modifier、textStyle等。
@Composable
fun TestView(
) {
Column {
val textFieldValue = remember { mutableStateOf(TextFieldValue("")) }
val list = remember { mutableStateListOf<String>("test") }
TextField(textFieldValue)
Button({
list.clear()
list.addAll(textFieldValue.value.text.split(""))
}) {
Text("Search")
}
list.forEach {
println("test $it")
Text(it)
}
}
}
@Composable
fun TextField(
textFieldValue: MutableState<TextFieldValue>,
) {
TextField(
value = textFieldValue.value,
onValueChange = { textFieldValue.value = it }
)
}
Run Code Online (Sandbox Code Playgroud)
我不确定为什么没有具有这种语义的系统函数,但在组合中他们更喜欢状态提升模式来匹配 UDF。
| 归档时间: |
|
| 查看次数: |
10901 次 |
| 最近记录: |