如何关闭可组合对话框?

9

我对Jetpack Compose很陌生,我想知道如何关闭可组合的对话框。 在Jetpack Compose中是否有类似于dismiss()的对话框函数?

使用以下代码,我无法通过触摸外部或按下返回按钮来关闭对话框。 对话框仍然可见于视图层次结构的顶部。

@Composable
fun InfoDialog() {
    val shouldDismiss = remember {
        mutableStateOf(false)
    }
    Dialog(onDismissRequest = {
        shouldDismiss.value = false
    }, properties = DialogProperties(
        dismissOnBackPress = true,
        dismissOnClickOutside = true
    )) {
        Card(
            shape = RoundedCornerShape(8.dp),
            modifier = Modifier.padding(16.dp,8.dp,16.dp,8.dp),
            elevation = 8.dp
        ) {
            Column(
                Modifier.background(c282534)) {
                Column(modifier = Modifier.padding(16.dp)) {
                    Text(
                        text = "Notice",
                        textAlign = TextAlign.Center,
                        modifier = Modifier
                            .padding(top = 8.dp)
                            .fillMaxWidth(),
                        style = TextStyle(fontWeight = FontWeight.Bold, color = Color.White, fontSize = 24.sp),
                        maxLines = 2,
                        overflow = TextOverflow.Ellipsis
                    )
                    Text(
                        text = "Allow Permission to send you notifications when important update added.",
                        textAlign = TextAlign.Center,
                        modifier = Modifier
                            .padding(top = 8.dp, start = 24.dp, end = 24.dp)
                            .fillMaxWidth(),
                        style = TextStyle(color = Color.White, fontSize = 16.sp)
                    )
                }
                Row(
                    Modifier
                        .fillMaxWidth()
                        .padding(top = 8.dp),
                    horizontalArrangement = Arrangement.SpaceAround) {

                    TextButton(onClick = {
                        shouldDismiss.value = true
                    }, modifier = Modifier.weight(1f)) {

                        Text(
                            "Close",
                            fontWeight = FontWeight.Normal,
                            color = Color.White,
                            modifier = Modifier.padding(top = 8.dp, bottom = 8.dp)
                        )
                    }
                    TextButton(
                        onClick = {
                        shouldDismiss.value = true
                        },
                        modifier = Modifier.weight(1f)
                    ) {
                        Text(
                            "Allow",
                            fontWeight = FontWeight.ExtraBold,
                            color = Color.White,
                            modifier = Modifier.padding(top = 8.dp, bottom = 8.dp)
                        )
                    }
                }
            }
        }
    }
}

`

2个回答

6
首先,您应该设置onDismissRequest,我猜在您的情况下它将是shouldDismiss.value = true。然后,您应该根据shouldDismiss值隐藏对话框。为了隐藏它,您只需要基于条件停止在代码中调用Dialog {...函数。例如,通过添加快速返回if (shouldDismiss.value) return。最终它会看起来像这样:
@Composable
fun InfoDialog() {
    val shouldDismiss = remember {
        mutableStateOf(false)
    }

    if (shouldDismiss.value) return
 
    Dialog(onDismissRequest = {
        shouldDismiss.value = true
    }, properties = DialogProperties(
        dismissOnBackPress = true,
        dismissOnClickOutside = true
    )) {
        Card(
            shape = RoundedCornerShape(8.dp),
            modifier = Modifier.padding(16.dp,8.dp,16.dp,8.dp),
            elevation = 8.dp
        ) {
            Column(
                Modifier.background(c282534)) {
                Column(modifier = Modifier.padding(16.dp)) {
                    Text(
                        text = "Notice",
                        textAlign = TextAlign.Center,
                        modifier = Modifier
                            .padding(top = 8.dp)
                            .fillMaxWidth(),
                        style = TextStyle(fontWeight = FontWeight.Bold, color = Color.White, fontSize = 24.sp),
                        maxLines = 2,
                        overflow = TextOverflow.Ellipsis
                    )
                    Text(
                        text = "Allow Permission to send you notifications when important update added.",
                        textAlign = TextAlign.Center,
                        modifier = Modifier
                            .padding(top = 8.dp, start = 24.dp, end = 24.dp)
                            .fillMaxWidth(),
                        style = TextStyle(color = Color.White, fontSize = 16.sp)
                    )
                }
                Row(
                    Modifier
                        .fillMaxWidth()
                        .padding(top = 8.dp),
                    horizontalArrangement = Arrangement.SpaceAround) {

                    TextButton(onClick = {
                        shouldDismiss.value = true
                    }, modifier = Modifier.weight(1f)) {

                        Text(
                            "Close",
                            fontWeight = FontWeight.Normal,
                            color = Color.White,
                            modifier = Modifier.padding(top = 8.dp, bottom = 8.dp)
                        )
                    }
                    TextButton(
                        onClick = {
                        shouldDismiss.value = true
                        },
                        modifier = Modifier.weight(1f)
                    ) {
                        Text(
                            "Allow",
                            fontWeight = FontWeight.ExtraBold,
                            color = Color.White,
                            modifier = Modifier.padding(top = 8.dp, bottom = 8.dp)
                        )
                    }
                }
            }
        }
    }
}


嗯,所以对话框仍然存在,我会通过调整其 alpha 值(不透明度)来隐藏它。这样正确吗? - Thái Quốc Toàn
不,compose函数在每次状态改变时都会被调用,我添加了if (shouldDismiss.value) return以跳过渲染对话框,如果shouldDismiss.value == true。这就是它的工作原理,你只需要根据某些条件不调用Dialog {...即可。 - Evgeny K
同时,您可以使用Kotlin代理语法:“val shouldDismiss by remember { `”,这样您就不必使用“shouldDismiss.value”,而只需使用“shouldDismiss”。 - Evgeny K
有没有办法让对话框消失?如你在我的问题中所看到的,我遇到了这样一个问题:无论是点击外部还是按下返回按钮,对话框都没有消失。 - Thái Quốc Toàn
当用户触摸屏幕外部或按下返回按钮时,对话框的 onDismissRequest 将被触发并更改 shouldDismiss 状态,然后 Compose 会重新调用 InfoDialog 组合函数,如果 Dialog inside 没有被调用,则它会消失 = 被解除(如果需要,您甚至可以添加动画效果)。 - Evgeny K
你刚刚帮我摆脱了困境,感谢你提供的有用建议。愉快编码! - Thái Quốc Toàn

3

只要对话框处于组合层次结构的一部分,它就是可见的。

你应该使用类似以下的内容:

val shouldShowDialog = remember { mutableStateOf(true) }

if (shouldShowDialog.value) {

    Dialog(onDismissRequest = { shouldShowDialog.value = false }) {            
        Button(onClick = {shouldShowDialog.value = false}){
                Text("Close")
        }
    }
}

shouldShowDialog设置为false会关闭Dialog。要显示它,只需将shouldShowDialog设置为true。类似这样:

Button(onClick = {shouldShowDialog.value = true}){
    Text("Open")
}

好的,我明白了。Dismiss并不等同于从视图层次结构中删除它。提前感谢。 - Thái Quốc Toàn
@TháiQuốcToàn 这是不正确的。openDialog是一个状态。这是因为在Compose中组合和重新组合的工作方式。remember计算出的值在初始组合期间存储在Composition中。对该value进行任何更改都将安排重组可读取该value的任何组合函数。 - Gabriele Mariotti
在这个例子中,它不是else语句。Dialog在层次结构中取决于if (openDialog.value)。要关闭Dialog,您需要将openDialog设置为false - Gabriele Mariotti
1
我现在明白了。非常抱歉我发表了不好的评论,所以我已经删除了它。再次感谢你的帮助! - Thái Quốc Toàn

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接