Okno dialogowe

Komponent Dialog wyświetla komunikaty w oknie lub prosi użytkownika o wprowadzenie danych w warstwie nad główną treścią aplikacji. Wyświetla interfejs, który przerywa użytkownikowi wykonywane czynności, aby przyciągnąć jego uwagę.

Oto niektóre przypadki użycia okna:

  • potwierdzanie działania użytkownika, np. podczas usuwania pliku;
  • Prośba o dane wejściowe użytkownika, np. w aplikacji z listą zadań.
  • Wyświetlanie listy opcji do wyboru przez użytkownika, np. wybór kraju podczas konfigurowania profilu.
Okno wypełnione tekstem i ikonami.
Rysunek 1. Przykład okna z tekstem i ikonami.

Okno dialogowe alertu

Kompozycja AlertDialog udostępnia wygodny interfejs API do tworzenia okna z motywem Material Design. AlertDialog ma określone parametry do obsługi poszczególnych elementów okna. Obejmują one:

  • title: tekst, który pojawia się u góry okna.
  • text: Tekst, który pojawia się na środku okna.
  • icon: grafika, która pojawia się u góry okna dialogowego.
  • onDismissRequest: funkcja wywoływana, gdy użytkownik zamyka okno, np. klikając poza nim.
  • dismissButton: komponent, który służy jako przycisk zamykania.
  • confirmButton: komponent, który służy jako przycisk potwierdzenia.

W przykładzie poniżej zaimplementowano 2 przyciski w oknie alertu: jeden zamyka okno, a drugi potwierdza żądanie.

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

Ta implementacja oznacza funkcję kompozycyjną nadrzędną, która przekazuje argumenty do funkcji kompozycyjnej podrzędnej w ten sposób:

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

Ta implementacja wygląda tak:

Otwarte okno alertu z przyciskami odrzucania i potwierdzania.
Rysunek 2. Okno alertu z przyciskami.

Kompozycja okna

Dialog to podstawowy komponent, który nie zapewnia żadnych stylów ani predefiniowanych miejsc na treści. Jest to stosunkowo prosty kontener, który należy wypełnić kontenerem takim jak Card. Oto niektóre z najważniejszych parametrów okna:

  • onDismissRequest: funkcja lambda wywoływana, gdy użytkownik zamknie okno.
  • properties: instancja klasy DialogProperties, która zapewnia dodatkowy zakres dostosowywania.
wewnętrzny kontener.

Podstawowy przykład

Poniższy przykład to podstawowa implementacja funkcji kompozycyjnej Dialog. Pamiętaj, że jako kontenera dodatkowego używa Card. Bez Card komponent Text wyświetlałby się samodzielnie nad główną treścią aplikacji.

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

Ta implementacja wygląda tak: Pamiętaj, że gdy okno jest otwarte, główna treść aplikacji pod nim jest przyciemniona i szara:

Okno, które zawiera tylko etykietę.
Rysunek 3. Minimalne okno dialogowe.

Przykład zaawansowany

Poniżej znajdziesz bardziej zaawansowaną implementację funkcji kompozycyjnej Dialog. W tym przypadku komponent ręcznie implementuje interfejs podobny do AlertDialog przykładu powyżej.

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

Ta implementacja wygląda tak:

Okno z zdjęciem góry Feathertop w stanie Wiktoria. Pod obrazem znajdują się przyciski odrzucania i potwierdzania.
Rysunek 4. okno dialogowe zawierające obraz;

Dodatkowe materiały