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

KMP Compose调用AlertDialog报错:仅可在@Composable上下文执行

问题原因及解决方法

你的错误出在直接在Button的onClick回调里调用AlertDialog——虽然外层Content()是@Composable函数,但onClick的lambda是普通回调函数,不属于Composable上下文,所以不能在这里调用AlertDialog这类Composable类型的函数,这就是报错的核心原因。

正确的做法是用状态控制Dialog的显示,而非在点击事件里直接创建Dialog。你已经定义了openDialog状态但未合理利用,按以下方式修改代码即可解决:

修正后的核心代码逻辑

@Composable
override fun Content() {
    val navigator = LocalNavigator.currentOrThrow
    // 新增状态:控制弹窗显示、存储错误提示信息
    val openErrorDialog = remember { mutableStateOf(false) }
    val errorMsg = remember { mutableStateOf("") }
    val realm = openPelletRealm()
    val pelletLots: RealmResults<PelletLot> = retrieveAllPellotLots(realm)

    MaterialTheme {
        Column(/* 原有布局代码保持不变 */) {
            // 原有列表、输入框等代码保持不变

            Row(/* 按钮行布局保持不变 */) {
                Button(onClick = {
                    closePelletRealm(realm)
                    navigator.pop()
                }) {
                    Text("Back")
                }
                Button(onClick = {
                    var hasError = false
                    for ((index, _) in textFields.withIndex()) {
                        val inputNum = textFields[index].value.toIntOrNull() ?: 0
                        if (pelletLots[index].numberOfPelletsInLot < inputNum) {
                            // 仅修改状态,触发弹窗显示
                            errorMsg.value = "批次${pelletLots[index].lotNumber}剩余颗粒不足"
                            openErrorDialog.value = true
                            hasError = true
                            break // 找到第一个错误即停止循环
                        }
                    }
                    // 无错误时才执行后续操作
                    if (!hasError) {
                        closePelletRealm(realm)
                        navigator.pop()
                    }
                }) {
                    Text("Submit")
                }
            }
        }

        // 在Composable上下文内,根据状态控制弹窗显示
        if (openErrorDialog.value) {
            AlertDialog(
                onDismissRequest = { openErrorDialog.value = false },
                title = { Text(text = "操作错误") },
                text = { Text(errorMsg.value) },
                confirmButton = {
                    Button(onClick = { openErrorDialog.value = false }) {
                        Text("确认")
                    }
                }
            )
        }
    }
}

关键修改点

  • 将AlertDialog从onClick回调中移出,放到Composable的UI树结构里,用openErrorDialog状态控制显示/隐藏
  • 在onClick回调中仅做业务逻辑判断,发现错误时修改状态变量,而非直接创建Dialog
  • 只有当所有校验通过时,才执行关闭Realm和页面返回的操作

这种写法既符合Composable的调用规则,也能正确实现错误提示的功能。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.27 05:43:23