Caixa de diálogo

O componente Dialog exibe mensagens pop-up ou solicita a entrada do usuário em uma camada acima do conteúdo principal do app. Ele cria uma experiência de interface interruptiva para chamar a atenção do usuário.

Entre os casos de uso de um diálogo, estão os seguintes:

  • Confirmar a ação do usuário, como ao excluir um arquivo.
  • Solicitar entradas do usuário, como em um app de lista de tarefas.
  • Apresentar uma lista de opções para seleção do usuário, como escolher um país em uma configuração de perfil.
Uma caixa de diálogo preenchida com texto e ícones.
Figura 1. Exemplo de uma caixa de diálogo preenchida com texto e ícones.

Caixa de diálogo de alerta

O elemento combinável AlertDialog fornece uma API conveniente para criar uma caixa de diálogo com o tema do Material Design. AlertDialog tem parâmetros específicos para processar elementos específicos da caixa de diálogo. Entre elas estão as seguintes:

  • title: o texto que aparece na parte de cima da caixa de diálogo.
  • text: o texto que aparece centralizado na caixa de diálogo.
  • icon: o gráfico que aparece na parte superior da caixa de diálogo.
  • onDismissRequest: a função chamada quando o usuário dispensa a caixa de diálogo, por exemplo, tocando fora dela.
  • dismissButton: um elemento combinável que serve como o botão "Dispensar".
  • confirmButton: um elemento combinável que serve como botão de confirmação.

O exemplo a seguir implementa dois botões em uma caixa de diálogo de alerta, um que dispensa a caixa e outro que confirma a solicitação.

@OptIn(ExperimentalMaterial3Api::class)
@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")
            }
        }
    )
}

Essa implementação implica que um elemento combinável pai transmite argumentos ao filho desta maneira:

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

Essa implementação aparece da seguinte maneira:

Uma caixa de diálogo de alerta aberta com os botões "Dispensar" e "Confirmar".
Figura 2. Uma caixa de diálogo de alerta com botões.

Elemento combinável de caixa de diálogo

Dialog é um elemento combinável básico que não fornece estilos ou slots predefinidos para o conteúdo. Ele é um contêiner relativamente simples que precisa ser preenchido com um contêiner como Card. Confira a seguir alguns dos principais parâmetros de uma caixa de diálogo:

  • onDismissRequest: o lambda chamado quando o usuário fecha a caixa de diálogo.
  • properties: uma instância de DialogProperties que fornece um escopo extra para personalização.

Exemplo básico

O exemplo abaixo é uma implementação básica do elemento combinável Dialog. Observe que ele usa um Card como o contêiner secundário. Sem o Card, o componente Text ficaria sozinho acima do conteúdo principal do app.

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

Essa implementação aparece da seguinte maneira: Quando a caixa de diálogo é aberta, o conteúdo principal do app abaixo dela aparece escurecido e esmaecido:

Uma caixa de diálogo que contém apenas um rótulo.
Figura 3. Caixa de diálogo mínima.

Exemplo avançado

Confira abaixo uma implementação mais avançada do elemento combinável Dialog. Nesse caso, o componente implementa manualmente uma interface semelhante ao exemplo AlertDialog acima.

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

Essa implementação aparece da seguinte maneira:

Caixa de diálogo com uma foto do Monte Feathertop, Victoria. Abaixo da imagem, há um botão para dispensar e um botão de confirmação.
Figura 4. Uma caixa de diálogo que inclui uma imagem.

Outros recursos