Jetpack Compose中Popup组件无法正确响应状态变更问题
Jetpack Compose Popup组件状态更新异常问题解决
问题重现
在使用Popup组件展示过滤后的列表时,当过滤条件导致列表为空,Popup内的UI无法同步更新,仍保留过滤前的元素。移除Popup组件后,列表UI能正常跟随状态变更。打印过滤后的列表长度显示为0,但Popup中的Text元素并未被移除。
相关代码:
@Composable fun Temp() { val a by remember { mutableStateOf((1..10).map { it.toString() }) } var textValue by remember { mutableStateOf("") } val list by remember { derivedStateOf { a.filter { it.contains(textValue) } } } Column { TextField( value = textValue, onValueChange = { value -> textValue = value } ) Box { Popup { Column { list.forEach { Text(text = it) } } } } } }
原因分析
Popup组件的内容Composable拥有独立的重组作用域,默认情况下,父组件的状态变更不会自动触发Popup内部的重组。当list状态变化时,Popup内部的遍历逻辑无法感知到状态更新,导致UI停留在旧状态。
解决方案
给Popup添加key参数,将过滤后的list作为key值。当list的内容发生变化时,key值会改变,从而强制Popup销毁并重新创建内部的UI内容,实现状态同步。
修正后的代码
@Composable fun Temp() { val a by remember { mutableStateOf((1..10).map { it.toString() }) } var textValue by remember { mutableStateOf("") } val list by remember { derivedStateOf { a.filter { it.contains(textValue) } } } Column { TextField( value = textValue, onValueChange = { value -> textValue = value } ) Box { // 添加key参数,绑定list状态 Popup(key = list) { Column { list.forEach { Text(text = it) } } } } } }
内容的提问来源于stack exchange,提问作者Diken Mhrz
相关产品推荐
相关产品推荐

