Dialog

Komponent Dialog wyświetla wyskakujące komunikaty lub prosi użytkownika o podanie danych w warstwie nad główną zawartością aplikacji. Tworzy on rozpraszający uwagę interfejs, aby przyciągnąć uwagę użytkownika.

Okno dialogowe może służyć na przykład:

  • potwierdzania działania użytkownika, na przykład podczas usuwania pliku.
  • Wymaganie od użytkownika danych wejściowych, np. w aplikacji z listą zadań.
  • Wyświetla się lista opcji do wyboru przez użytkownika, np. wybór kraju w konfiguracji profilu.
Okno zawierające tekst i ikony.
Rysunek 1. Przykład okna zawierającego tekst i ikony.

Okno dialogowe alertu

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

  • title: tekst, który pojawia się u góry okna.
  • text: tekst wyświetlany na środku okna dialogowego.
  • icon: grafika wyświetlana u góry okna.
  • onDismissRequest: funkcja wywoływana, gdy użytkownik zamknie okno, np. kliknie poza nim.
  • dismissButton: element kompozycyjny, który służy jako przycisk zamykania.
  • confirmButton: element kompozycyjny, który służy jako przycisk potwierdzenia.

Poniższy przykład pokazuje 2 przyciski w oknie alertu: jeden zamykający to okno i drugi do potwierdzenia żądania.

@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ędna funkcja kompozycyjna przekazuje argumenty do elementu podrzędnego 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 z przyciskami zamykania i potwierdzenia.
Rysunek 2. Okno alertu z przyciskami.

Okno z możliwością tworzenia

Dialog to podstawowa funkcja kompozycyjna, która nie zawiera żadnych stylów ani wstępnie zdefiniowanych przedziałów na treści. Jest to stosunkowo prosty kontener, który należy zapełnić kontenerem takim jak Card. Oto niektóre z najważniejszych parametrów okna dialogowego:

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

Podstawowy przykład

Poniższy przykład pokazuje podstawową implementację funkcji kompozycyjnej Dialog. Uwaga: kontener dodatkowy używa Card. Bez Card komponent Text byłby wyświetlany 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,
            )
        }
    }
}

Implementacja wygląda tak. Pamiętaj, że po otwarciu okna główna zawartość aplikacji pod nim jest przyciemniona i wyszarzona:

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

Przykład zaawansowany

Poniżej przedstawiliśmy bardziej zaawansowaną implementację funkcji kompozycyjnej Dialog. W takim przypadku komponent ręcznie implementuje interfejs podobny do interfejsu przykładowego 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 Victoria. Pod obrazem znajdują się przyciski zamykania i potwierdzenia.
Rysunek 4. Okno z obrazem.

Dodatkowe materiały