You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.21 07:22:37