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

展开状态的ExposedDropdownMenu导航至其他Fragment时致应用崩溃

解决方案:ExposedDropdownMenu导航时PopupLayout崩溃问题

这个崩溃的核心原因是:导航操作触发Fragment/Compose销毁时,ExposedDropdownMenu的PopupLayout还没来得及从WindowManager中移除,后续它尝试更新布局时找不到关联的Window,就抛出了异常。你已经尝试在导航前收起菜单,但Compose的状态更新是异步的,导航操作同步执行导致时机不匹配。

以下是几个可行的解决办法:

1. 等待菜单收起状态生效后再导航

利用LaunchedEffect监听菜单展开状态,仅当状态确实变为收起后再执行导航操作,确保Compose完成重组、Popup已被移除:

// ViewModel中托管状态
class YourViewModel : ViewModel() {
    val isDropdownExpanded = mutableStateOf(false)
    // 其他状态...
}

// Composable代码
@Composable
fun YourScreen(viewModel: YourViewModel, navController: NavController) {
    val isExpanded by viewModel.isDropdownExpanded

    // 监听菜单收起事件,执行导航
    LaunchedEffect(isExpanded) {
        if (!isExpanded) {
            // 这里执行导航
            navController.navigate("target_screen")
        }
    }

    Button(
        onClick = {
            // 先收起菜单,触发状态更新
            viewModel.isDropdownExpanded.value = false
        }
    ) {
        Text("跳转")
    }

    // 你的ExposedDropdownMenu代码
    ExposedDropdownMenu(
        expanded = isExpanded,
        onDismissRequest = { viewModel.isDropdownExpanded.value = false }
    ) {
        // 菜单选项...
    }
}

2. 禁用导航按钮直到菜单完全收起

在菜单展开时,将导航按钮设为不可点击,从源头避免用户在菜单未收起时触发导航:

Button(
    onClick = {
        navController.navigate("target_screen")
    },
    enabled = !isExpanded // 菜单展开时禁用按钮
) {
    Text("跳转")
}

3. 在Compose销毁前强制清理菜单

利用DisposableEffect,在Composable即将离开组合时,强制收起菜单,确保Popup被正确移除:

@Composable
fun YourScreen(viewModel: YourViewModel, navController: NavController) {
    val isExpanded by viewModel.isDropdownExpanded

    // 当Compose离开组合时,强制收起菜单
    DisposableEffect(Unit) {
        onDispose {
            viewModel.isDropdownExpanded.value = false
        }
    }

    // 其余代码...
}

4. 应急方案:延迟导航(不推荐)

如果以上方案暂时无法适配,可以给菜单收起留一点缓冲时间再导航,但这种方式依赖设备性能,不是最优解:

Button(
    onClick = {
        viewModel.isDropdownExpanded.value = false
        // 延迟200ms再导航,给Popup足够的销毁时间
        CoroutineScope(Dispatchers.Main).launch {
            delay(200)
            navController.navigate("target_screen")
        }
    }
) {
    Text("跳转")
}

内容的提问来源于stack exchange,提问作者Ygor

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 18:55:23