Composable确认对话框调用报错:仅能在Composable上下文调用
问题原因与解决方案
错误原因
你在IconButton的onClick回调里直接调用了ConfirmationDialog这个@Composable函数,但onClick是普通的点击事件回调(非@Composable上下文),Jetpack Compose要求所有@Composable函数必须在@Composable上下文中调用,因此触发了该错误。
解决步骤
我们需要用状态变量控制对话框的显示/隐藏,将对话框的调用移到合法的@Composable上下文中:
- 在
NoteScreen函数内部添加状态变量,跟踪对话框是否显示:
val showDeleteDialog = remember { mutableStateOf(false) }
- 修改删除按钮的
onClick逻辑,仅更新状态变量,不再直接调用对话框:
IconButton( onClick = { showDeleteDialog.value = true } ) { Icon( imageVector = Icons.Rounded.Delete, contentDescription = "delete" ) }
- 在
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
相关产品推荐
相关产品推荐

