Как закрыть составной диалог?

Я новичок в создании реактивного ранца, и мне действительно хотелось знать, как я могу закрыть компонуемый диалог. Есть ли какая-нибудь функция, такая как уволить () для диалога в компоновке реактивного ранца?

Используя приведенный ниже код, я не могу закрыть диалоговое окно, касающееся снаружи или нажав кнопку «Назад». Диалог все еще виден в верхней части иерархии представлений. `

@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)
                        )
                    }
                }
            }
        }
    }
}

`

4
0
394
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Во-первых, вы должны настроить 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)
                        )
                    }
                }
            }
        }
    }
}

Хм, значит, диалог все еще там, и я бы скрыл его, отрегулировав его альфа-канал (непрозрачность). Это правильно?

Thái Quốc Toàn 20.11.2022 10:26

нет, функция компоновки вызывается каждый раз при изменении вашего состояния, я добавил if (shouldDismiss.value) return, чтобы пропустить диалог рендеринга, если shouldDismiss.value == true. Вот как это работает, вы просто не вызываете Dialog {... на основе какого-то условия

Evgeny 20.11.2022 10:32

также вы можете использовать синтаксис делегата kotlin: val shouldDismiss by remember { тогда вам не нужно использовать shouldDismiss.value и просто использовать shouldDismiss вместо этого

Evgeny 20.11.2022 10:34

Есть ли способ, чтобы диалог исчез? Как вы видите, в моем вопросе у меня возникла проблема, что диалоговое окно не исчезло ни при касании снаружи, ни при нажатии кнопки «Назад».

Thái Quốc Toàn 20.11.2022 10:41

когда пользователь касается снаружи или нажимает кнопку «Назад», диалоговое окно onDismissRequest запускается и состояние shouldDismiss изменяется, затем Compose повторно вызывает InfoDialog компонуемую функцию, и если Dialog inside не вызывается, то она исчезает = закрывается (если вы хотите, вы можете даже анимировать это)

Evgeny 20.11.2022 10:45

Ты просто выводишь меня из моего беспорядка. Также спасибо за полезные предложения. Удачного кодирования!

Thái Quốc Toàn 20.11.2022 11:04
Ответ принят как подходящий

Диалог виден до тех пор, пока он является частью иерархии композиции. Вы должны использовать что-то вроде:

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")
}

Ну, у меня есть идея. Отклонение не равносильно удалению из иерархии представлений. Заранее спасибо

Thái Quốc Toàn 20.11.2022 10:33

@TháiQuốcToàn Это неправильно. openDialog — это состояние. Это связано с тем, как композиция и рекомпозиция работают в Compose. Значение, вычисленное remember, сохраняется в композиции во время первоначальной композиции. Любые изменения значения запланируют перекомпоновку любых составных функций, которые читают это value.

Gabriele Mariotti 20.11.2022 10:38

Это пример, это не утверждение else. Диалог находится в иерархии в зависимости от if (openDialog.value). Чтобы закрыть диалоговое окно, вы должны установить openDialog на false.

Gabriele Mariotti 20.11.2022 10:51

Теперь я понимаю. Очень извиняюсь за мой плохой комментарий, поэтому я удалил его. Я снова ценю вашу помощь!

Thái Quốc Toàn 20.11.2022 11:01

Другие вопросы по теме