Okno dialogowe

Komponent Dialog wyświetla komunikaty w oknie lub prosi użytkownika o wprowadzenie danych wejściowych użytkownika w warstwie nad główną treścią aplikacji. Wyświetla interfejs, który przerywa użytkownikowi korzystanie z aplikacji, 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. wyboru kraju podczas konfigurowania profilu.
okno z 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 dialogowego 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 wyświetlana u góry okna.
  • onDismissRequest: funkcja wywoływana, gdy użytkownik zamyka okno dialogowe, 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 tym przykładzie w oknie alertu zaimplementowano 2 przyciski: 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 żadnego stylu 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 kluczowych parametrów dialogu:

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

Podstawowy przykład

Poniższy przykład to podstawowa implementacja funkcji kompozycyjnej Dialog. Zwróć uwagę, ż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 dialogowe jest otwarte, główna treść aplikacji pod nim jest przyciemniona i szara:

Okno dialogowe zawierające tylko etykietę.
Rysunek 3. Minimalne okno.

Zaawansowany przykład

Poniżej znajdziesz bardziej zaawansowaną implementację funkcji kompozycyjnej Dialog. W tym przypadku komponent ręcznie implementuje interfejs podobny do interfejsu w przykładzie 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")
                    }
                }
            }
        }
    }
}

Ta implementacja wygląda tak:

Okno dialogowe z widokiem góry Mount Feathertop w stanie Wiktoria, z przyciskiem zamknięcia i przyciskiem potwierdzenia.
Rysunek 4. Okno dialogowe zawierające obraz.

Dodatkowe materiały