Cuadro de diálogo

El componente Dialog muestra mensajes de diálogo o solicita la entrada del usuario en una capa sobre el contenido principal de la app. Crea una experiencia de IU interruptiva para captar la atención del usuario.

Entre los casos de uso de un diálogo, se incluyen los siguientes:

  • Confirmar la acción del usuario, como cuando se borra un archivo
  • Solicitar la entrada del usuario, como en una app de lista de tareas pendientes
  • Presentar una lista de opciones para que el usuario seleccione, como elegir un país en la configuración del perfil
Un diálogo completado con texto e íconos.
Figura 1. Ejemplo de un diálogo con texto y íconos

Cuadro de diálogo de alerta

El elemento componible AlertDialog proporciona una API conveniente para crear un diálogo con el tema de Material Design. AlertDialog tiene parámetros específicos para controlar elementos particulares del diálogo. Entre ellos, se incluyen los siguientes:

  • title: Es el texto que aparece en la parte superior del diálogo.
  • text: Es el texto que aparece centrado dentro del diálogo.
  • icon: Es el gráfico que aparece en la parte superior del diálogo.
  • onDismissRequest: Es la función a la que se llama cuando el usuario descarta el diálogo, por ejemplo, presionando fuera de él.
  • dismissButton: Es un elemento componible que sirve como botón de descartar.
  • confirmButton: Es un elemento componible que sirve como botón de confirmación.

En el siguiente ejemplo, se implementan dos botones en un cuadro de diálogo de alerta: uno que descarta el diálogo y otro que confirma su solicitud.

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

Esta implementación implica un elemento componible superior que pasa argumentos al elemento componible secundario de esta manera:

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

Esta implementación aparece de la siguiente manera:

Es un diálogo de alerta abierto que tiene botones para descartar y confirmar.
Figura 2. Un cuadro de diálogo de alerta con botones

Elemento componible de diálogo

Dialog es un elemento componible básico que no proporciona ningún estilo ni espacios predefinidos para el contenido. Es un contenedor relativamente sencillo que debes completar con un contenedor como Card. Los siguientes son algunos de los parámetros clave de un diálogo:

  • onDismissRequest: Es la expresión lambda a la que se llama cuando el usuario cierra el diálogo.
  • properties: Es una instancia de DialogProperties que proporciona un alcance adicional para la personalización.

Ejemplo básico

El siguiente ejemplo es una implementación básica del elemento componible Dialog. Ten en cuenta que usa una Card como contenedor secundario. Sin la Card, el componente Text aparecería solo sobre el contenido principal de la 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,
            )
        }
    }
}

Esta implementación aparece de la siguiente manera. Ten en cuenta que, cuando el diálogo está abierto, el contenido principal de la app que se encuentra debajo aparece oscurecido y atenuado:

Es un diálogo que no contiene nada más que una etiqueta.
Figura 3. Diálogo mínimo

Ejemplo avanzado

La siguiente es una implementación más avanzada del elemento componible Dialog. En este caso, el componente implementa manualmente una interfaz similar al ejemplo de AlertDialog anterior.

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

Esta implementación aparece de la siguiente manera:

Un diálogo con una foto del monte Feathertop, Victoria. Debajo de la imagen, hay un botón para descartar y otro para confirmar.
Figura 4. Un diálogo que incluye una imagen

Recursos adicionales