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

Composable确认对话框调用报错:仅能在Composable上下文调用

问题原因与解决方案

错误原因

你在IconButton的onClick回调里直接调用了ConfirmationDialog这个@Composable函数,但onClick是普通的点击事件回调(非@Composable上下文),Jetpack Compose要求所有@Composable函数必须在@Composable上下文中调用,因此触发了该错误。

解决步骤

我们需要用状态变量控制对话框的显示/隐藏,将对话框的调用移到合法的@Composable上下文中:

  1. 在NoteScreen函数内部添加状态变量,跟踪对话框是否显示:
val showDeleteDialog = remember { mutableStateOf(false) }
  1. 修改删除按钮的onClick逻辑,仅更新状态变量,不再直接调用对话框:
IconButton(
    onClick = {
        showDeleteDialog.value = true
    }
) {
    Icon(
        imageVector = Icons.Rounded.Delete,
        contentDescription = "delete"
    )
}
  1. 在NoteScreen的Composable层级中(比如Scaffold之后),根据状态变量决定是否显示对话框:
if (showDeleteDialog.value) {
    ConfirmationDialog(
        title = "Confirm Action",
        message = "Would you like to delete this message?",
        cancelText = "Cancel",
        confirmText = "Ok",
        onConfirm = {
            onEvent(NoteEvent.DeleteNote)
            showDeleteDialog.value = false
        },
        onDismiss = {
            showDeleteDialog.value = false
        }
    )
}

修改后的完整NoteScreen代码

@Composable
fun NoteScreen(
    state: NoteState,
    onEvent: (NoteEvent) -> Unit
) {
    val showDeleteDialog = remember { mutableStateOf(false) }

    Scaffold(
        topBar = {
            CenterAlignedTopAppBar(
                title = { /*TODO*/ },
                navigationIcon = {
                    IconButton(
                        onClick = {
                            onEvent(NoteEvent.NavigateBack)
                        }
                    ) {
                        Icon(
                            imageVector = Icons.Rounded.ArrowBack,
                            contentDescription = "navigate back"
                        )
                    }
                },
                actions = {
                    IconButton(
                        onClick = {
                            showDeleteDialog.value = true
                        }
                    ) {
                        Icon(
                            imageVector = Icons.Rounded.Delete,
                            contentDescription = "delete")
                    }
                }
            )
        }
    ) { padding ->
        Column(
            modifier = Modifier
                .fillMaxSize()
                .padding(padding)
                .padding(
                    horizontal = 20.dp,
                    vertical = 15.dp
                ),
            verticalArrangement = Arrangement.spacedBy(10.dp),
            horizontalAlignment = Alignment.CenterHorizontally,
        ) {
              OutlinedTextField (
                  value = state.title,
                  onValueChange = {
                      onEvent(NoteEvent.TitleChange(it))
                  },
                  placeholder = {
                      Text(text = "Title")
                  }
              )
            OutlinedTextField (
                value = state.content,
                onValueChange = {
                    onEvent(NoteEvent.ContentChange(it))
                },
                placeholder = {
                    Text(text = "Content")
                }

            )
            OutlinedTextField (
                value = state.timeStamp,
                onValueChange = {
                    onEvent(NoteEvent.TimeStampChange(it))
                },
                placeholder = {
                    Text(text = "Time Stamp")
                },
            )
            
            Box(
                modifier = Modifier
                    .fillMaxSize()
                    .padding(vertical = 8.dp)
                    .align(Alignment.CenterHorizontally)
            ) {
                Button(
                    onClick = {
                        onEvent(NoteEvent.Save)
                    },
                    modifier = Modifier
                        .fillMaxWidth(0.5f)
                        .align(Alignment.TopCenter)
                ) {
                    Text(text = "Save")
                }
            }
        }
    }

    // 显示对话框
    if (showDeleteDialog.value) {
        ConfirmationDialog(
            title = "Confirm Action",
            message = "Would you like to delete this message?",
            cancelText = "Cancel",
            confirmText = "Ok",
            onConfirm = {
                onEvent(NoteEvent.DeleteNote)
                showDeleteDialog.value = false
            },
            onDismiss = {
                showDeleteDialog.value = false
            }
        )
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 23:47:31