Jetpack Compose中SimpleAlertDialog的Composable上下文调用错误
解决Jetpack Compose中在非Composable回调内调用Composable组件的错误
你遇到的错误核心原因是:combinedClickable的onLongClick是普通Lambda回调,不属于@Composable上下文,而SimpleAlertDialog是带@Composable注解的组件,必须在其他@Composable函数或标记了@Composable的Lambda中调用。
解决方案
正确的做法是用状态变量控制对话框的显示/隐藏,而非直接在回调内调用Composable组件。具体实现如下:
@OptIn(ExperimentalFoundationApi::class) @Composable fun MyCharactersListRowView( viewmodel: MainViewModel, characterModel: CharacterModel, popBack: () -> Unit ) { val (characterSelected, setCharacterSelected) = remember { mutableStateOf<CharacterModel?>(null) } val openDialog = remember { mutableStateOf(false) } // 将对话框放在Composable顶层,由openDialog状态控制显示 SimpleAlertDialog( hero = characterSelected, show = openDialog.value, onConfirm = { characterSelected?.let { selected -> viewmodel.deleteCharacter(selected.id.toLong()) Log.d("info", "rowAffected: ${viewmodel.rowAffected.value}") val context = LocalContext.current if (viewmodel.rowAffected.value.toInt() != 0) { Toast.makeText( context, "¡ ${selected.name} 删除成功!", Toast.LENGTH_LONG ).show() } else { Toast.makeText( context, viewmodel.loadError.value, Toast.LENGTH_LONG ).show() } openDialog.value = false } }, onDismiss = { openDialog.value = false }, textTittle = "Remove character", textDescription = characterSelected?.let { "Would you like to remove ${it.name} from your characters?" } ?: "" ) Row( modifier = Modifier .fillMaxWidth() .clickable(onClick = { setCharacterSelected(characterModel) }) .padding(vertical = 8.dp, horizontal = 16.dp), verticalAlignment = Alignment.CenterVertically ){ AsyncImage( model = characterModel.image, contentDescription = characterModel.name, contentScale = ContentScale.Fit, modifier = Modifier .size(60.dp) .clip(CircleShape) .combinedClickable( onLongClick = { // 仅更新状态,不直接调用Composable setCharacterSelected(characterModel) openDialog.value = true }, onClick = { // TODO: 处理点击逻辑 } ) ) Text( text = characterModel.name, modifier = Modifier.padding(start = 16.dp) ) } }
关键改动说明
- 将
SimpleAlertDialog移到MyCharactersListRowView的顶层,确保处于Composable上下文内,符合组件调用规则。 onLongClick回调仅负责更新状态变量,不再直接调用Composable组件,逻辑更简洁合规。- 用
let安全处理characterSelected为空的潜在问题,避免空指针异常。 - 简化原代码中冗余的链式调用,提升逻辑可读性。
内容的提问来源于stack exchange,提问作者Manuel Lucas
相关产品推荐
相关产品推荐

