Dialog

Komponent Dialog wyświetla komunikaty w wyskakującym okienku lub prosi o wpisanie danych wejściowych użytkownika w warstwie nad główną zawartością aplikacji. Tworzy on przerywające działanie interfejsu, aby przyciągnąć uwagę użytkownika.

Okno może służyć do takich zastosowań:

  • Potwierdzenie działania użytkownika, na przykład usunięcie pliku.
  • Proszenie użytkownika o podanie danych wejściowych, np. w aplikacji do obsługi listy zadań.
  • Wyświetlanie listy opcji do wyboru przez użytkownika, np. wyboru kraju w konfiguracji profilu.
Okno z tekstem i ikonami.
Rysunek 1. Przykład okna z tekstem i ikonami.

Okno dialogowe alertu

Funkcja kompozycyjna AlertDialog to wygodny interfejs API do tworzenia okna z motywem Material Design. AlertDialog ma określone parametry do obsługi konkretnych elementów okna. Oto niektóre z nich:

  • title: tekst wyświetlany na górze okna.
  • text: tekst, który będzie wyśrodkowany w oknie.
  • icon: grafika wyświetlana na górze okna.
  • onDismissRequest: funkcja wywoływana, gdy użytkownik zamknie okno, na przykład klikając je poza nim.
  • dismissButton: funkcja kompozycyjna, która służy jako przycisk zamykania.
  • confirmButton: funkcja kompozycyjna, która służy jako przycisk potwierdzenia.

W poniższym przykładzie implementujemy 2 przyciski w oknie alertu: jeden zamykający je, a drugi, który potwierdza jego żądanie.

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

Ta implementacja zakłada, że nadrzędny element kompozycyjny przekazuje argumenty do podrzędnego elementu kompozycyjnego 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
                )
            }
        }
    }
}

Implementacja wygląda tak:

Otwarte okno alertu, które zawiera zarówno przycisk zamykania, jak i potwierdzenia.
Rysunek 2. Okno alertu z przyciskami.

Okno kompozycyjne

Dialog to podstawowy element kompozycyjny, który nie udostępnia żadnych stylów ani wstępnie zdefiniowanych boksów na treść. To stosunkowo prosty kontener, który należy wypełnić takim kontenerem, np. Card. Oto niektóre z kluczowych parametrów okna:

  • onDismissRequest: funkcja lambda jest wywoływana, gdy użytkownik zamknie okno.
  • properties: wystąpienie elementu DialogProperties, które zapewnia dodatkowy zakres dostosowywania.

Podstawowy przykład

Ten przykład przedstawia podstawową implementację funkcji kompozycyjnej Dialog. Pamiętaj, że używany jest Card jako kontener dodatkowy. Bez Card komponent Text wydałby się sam nad główną zawartoś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,
            )
        }
    }
}

Implementacja wygląda tak: Pamiętaj, że po otwarciu okna główna treść aplikacji pod nim będzie zaciemniona i wyszarzona:

Okno, które nie zawiera nic poza etykietą.
Rysunek 3. Minimalne okno dialogowe.

Przykład zaawansowany

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

Implementacja wygląda tak:

Okno ze zdjęciem góry Feathertop w stanie Wiktoria. Pod obrazem znajdują się przyciski zamykania i potwierdzenia.
Rysunek 4. Okno z obrazem.

Dodatkowe materiały