Диалог

Компонент Dialog отображает диалоговые сообщения или запрашивает ввод данных у пользователя на уровне, расположенном над основным содержимым приложения. Он создает отвлекающий пользовательский интерфейс, призванный привлечь внимание пользователя.

К числу вариантов использования диалога относятся следующие:

  • Подтверждение действий пользователя, например, при удалении файла.
  • Запрос ввода данных от пользователя, например, в приложении для составления списка дел.
  • Представление пользователю списка вариантов выбора, аналогичного выбору страны при настройке профиля.
Диалоговое окно, содержащее текст и значки.
Рисунок 1. Пример диалогового окна, заполненного текстом и значками.

Диалоговое окно предупреждения

Компонент AlertDialog предоставляет удобный API для создания диалогового окна в стиле Material Design. AlertDialog имеет специальные параметры для обработки отдельных элементов диалогового окна. Среди них следующие:

  • title : Текст, отображаемый в верхней части диалогового окна.
  • text : Текст, который отображается по центру в диалоговом окне.
  • icon : графическое изображение, которое отображается в верхней части диалогового окна.
  • onDismissRequest : Функция, вызываемая, когда пользователь закрывает диалоговое окно, например, касаясь его внешней стороны.
  • dismissButton : Составной объект, выполняющий функцию кнопки закрытия.
  • confirmButton : Составной объект, выполняющий функцию кнопки подтверждения.

В следующем примере реализованы две кнопки в диалоговом окне предупреждения: одна закрывает диалог, а другая подтверждает запрос.

@Composable
fun AlertDialogExample(
    onDismissRequest: () -> Unit,
    onConfirmation: () -> Unit,
    dialogTitle: String,
    dialogText: String,
    icon: ImageVector,
) {
    AlertDialog(
        icon = {
            Icon(icon, contentDescription = "Example Icon")
        },
        title = {
            Text(text = dialogTitle)
        },
        text = {
            Text(text = dialogText)
        },
        onDismissRequest = {
            onDismissRequest()
        },
        confirmButton = {
            TextButton(
                onClick = {
                    onConfirmation()
                }
            ) {
                Text("Confirm")
            }
        },
        dismissButton = {
            TextButton(
                onClick = {
                    onDismissRequest()
                }
            ) {
                Text("Dismiss")
            }
        }
    )
}

Данная реализация подразумевает наличие родительского компонента, который передает аргументы дочернему компоненту следующим образом:

@Composable
fun DialogExamples() {
    // ...
    val openAlertDialog = remember { mutableStateOf(false) }

    // ...
        when {
            // ...
            openAlertDialog.value -> {
                AlertDialogExample(
                    onDismissRequest = { openAlertDialog.value = false },
                    onConfirmation = {
                        openAlertDialog.value = false
                        println("Confirmation registered") // Add logic here to handle confirmation.
                    },
                    dialogTitle = "Alert dialog example",
                    dialogText = "This is an example of an alert dialog with buttons.",
                    icon = Icons.Default.Info
                )
            }
        }
    }
}

Данная реализация выглядит следующим образом:

Открытое диалоговое окно с предупреждением, содержащее кнопки «Закрыть» и «Подтвердить».
Рисунок 2. Диалоговое окно с кнопками.

Диалоговый составной

Dialog — это базовый компонент, который не предоставляет никаких стилей или предопределенных слотов для контента. Это относительно простой контейнер, который следует заполнять контейнером, например, Card . Ниже приведены некоторые ключевые параметры диалогового окна:

  • onDismissRequest : Лямбда-функция, вызываемая при закрытии пользователем диалогового окна.
  • properties : Экземпляр класса DialogProperties , предоставляющий дополнительные возможности для настройки.

Простой пример

Следующий пример представляет собой базовую реализацию компонента Dialog . Обратите внимание, что в качестве дополнительного контейнера используется Card . Без Card компонент Text отображался бы отдельно над основным содержимым приложения.

@Composable
fun MinimalDialog(onDismissRequest: () -> Unit) {
    Dialog(onDismissRequest = { onDismissRequest() }) {
        Card(
            modifier = Modifier
                .fillMaxWidth()
                .height(200.dp)
                .padding(16.dp),
            shape = RoundedCornerShape(16.dp),
        ) {
            Text(
                text = "This is a minimal dialog",
                modifier = Modifier
                    .fillMaxSize()
                    .wrapContentSize(Alignment.Center),
                textAlign = TextAlign.Center,
            )
        }
    }
}

Данная реализация выглядит следующим образом. Обратите внимание, что когда диалоговое окно открыто, основное содержимое приложения под ним отображается затемненным и серым:

Диалоговое окно, содержащее лишь подпись.
Рисунок 3. Минимальный диалог.

Расширенный пример

Ниже представлена ​​более продвинутая реализация компонента Dialog . В этом случае компонент вручную реализует интерфейс, аналогичный примеру AlertDialog , приведенному выше.

@Composable
fun DialogWithImage(
    onDismissRequest: () -> Unit,
    onConfirmation: () -> Unit,
    painter: Painter,
    imageDescription: String,
) {
    Dialog(onDismissRequest = { onDismissRequest() }) {
        // Draw a rectangle shape with rounded corners inside the dialog
        Card(
            modifier = Modifier
                .fillMaxWidth()
                .height(375.dp)
                .padding(16.dp),
            shape = RoundedCornerShape(16.dp),
        ) {
            Column(
                modifier = Modifier
                    .fillMaxSize(),
                verticalArrangement = Arrangement.Center,
                horizontalAlignment = Alignment.CenterHorizontally,
            ) {
                Image(
                    painter = painter,
                    contentDescription = imageDescription,
                    contentScale = ContentScale.Fit,
                    modifier = Modifier
                        .height(160.dp)
                )
                Text(
                    text = "This is a dialog with buttons and an image.",
                    modifier = Modifier.padding(16.dp),
                )
                Row(
                    modifier = Modifier
                        .fillMaxWidth(),
                    horizontalArrangement = Arrangement.Center,
                ) {
                    TextButton(
                        onClick = { onDismissRequest() },
                        modifier = Modifier.padding(8.dp),
                    ) {
                        Text("Dismiss")
                    }
                    TextButton(
                        onClick = { onConfirmation() },
                        modifier = Modifier.padding(8.dp),
                    ) {
                        Text("Confirm")
                    }
                }
            }
        }
    }
}

Данная реализация выглядит следующим образом:

Диалоговое окно с фотографией горы Фезертоп, штат Виктория. Под изображением расположены кнопки «Закрыть» и «Подтвердить».
Рисунок 4. Диалоговое окно, содержащее изображение.

Дополнительные ресурсы