Finestre di dialogo per i selettori dell'ora

I selettori di ora vengono spesso visualizzati nelle finestre di dialogo. Puoi utilizzare un'implementazione relativamente generica e minima di una finestra di dialogo oppure puoi implementare una finestra di dialogo personalizzata con maggiore flessibilità.

Per ulteriori informazioni sulle finestre di dialogo in generale, inclusa la modalità di utilizzo dello stato del selettore dell'ora, consulta la guida ai selettori dell'ora.

Esempio di base

Il modo più semplice per creare una finestra di dialogo per il selettore dell'ora è creare un composable che implementi AlertDialog. Lo snippet riportato di seguito fornisce un esempio di finestra di dialogo relativamente minima che utilizza questo approccio:

@Composable
fun DialWithDialogExample(
    onConfirm: (TimePickerState) -> Unit,
    onDismiss: () -> Unit,
) {
    val currentTime = Calendar.getInstance()

    val timePickerState = rememberTimePickerState(
        initialHour = currentTime.get(Calendar.HOUR_OF_DAY),
        initialMinute = currentTime.get(Calendar.MINUTE),
        is24Hour = true,
    )

    TimePickerDialog(
        onDismiss = { onDismiss() },
        onConfirm = { onConfirm(timePickerState) }
    ) {
        TimePicker(
            state = timePickerState,
        )
    }
}

@Composable
fun TimePickerDialog(
    onDismiss: () -> Unit,
    onConfirm: () -> Unit,
    content: @Composable () -> Unit
) {
    AlertDialog(
        onDismissRequest = onDismiss,
        dismissButton = {
            TextButton(onClick = { onDismiss() }) {
                Text("Dismiss")
            }
        },
        confirmButton = {
            TextButton(onClick = { onConfirm() }) {
                Text("OK")
            }
        },
        text = { content() }
    )
}

Tieni presente i punti chiave di questo snippet:

  1. Il composable DialWithDialogExample inserisce TimePicker in una finestra di dialogo.
  2. TimePickerDialog è un composable personalizzato che crea un AlertDialog con i seguenti parametri:
    • onDismiss: una funzione chiamata quando l'utente ignora la finestra di dialogo (tramite il pulsante di chiusura o il pulsante Indietro).
    • onConfirm: una funzione chiamata quando l'utente fa clic sul pulsante "Ok".
    • content: un composable che mostra il selettore dell'ora all'interno della finestra di dialogo.
  3. AlertDialog include:
    • Un pulsante di chiusura denominato "Chiudi".
    • Un pulsante di conferma denominato "OK".
    • I contenuti del selettore dell'ora passati come parametro text.
  4. DialWithDialogExample inizializza TimePickerState con il tempo corrente e lo passa sia alla funzione TimePicker sia alla funzione onConfirm.
Un selettore dell'ora in un AlertDialog che implementa un titolo, un pulsante di attivazione/disattivazione della modalità e i pulsanti di chiusura e conferma.
Figura 1. Un selettore dell'ora in un AlertDialog.

Esempio avanzato

Questo snippet mostra un'implementazione avanzata di una finestra di dialogo di selezione dell'ora personalizzabile in Jetpack Compose.

@Composable
fun AdvancedTimePickerExample(
    onConfirm: (TimePickerState) -> Unit,
    onDismiss: () -> Unit,
) {

    val currentTime = Calendar.getInstance()

    val timePickerState = rememberTimePickerState(
        initialHour = currentTime.get(Calendar.HOUR_OF_DAY),
        initialMinute = currentTime.get(Calendar.MINUTE),
        is24Hour = true,
    )

    /** Determines whether the time picker is dial or input */
    var showDial by remember { mutableStateOf(true) }

    /** The icon used for the icon button that switches from dial to input */
    val toggleIcon = if (showDial) {
        Icons.Filled.EditCalendar
    } else {
        Icons.Filled.AccessTime
    }

    AdvancedTimePickerDialog(
        onDismiss = { onDismiss() },
        onConfirm = { onConfirm(timePickerState) },
        toggle = {
            IconButton(onClick = { showDial = !showDial }) {
                Icon(
                    imageVector = toggleIcon,
                    contentDescription = "Time picker type toggle",
                )
            }
        },
    ) {
        if (showDial) {
            TimePicker(
                state = timePickerState,
            )
        } else {
            TimeInput(
                state = timePickerState,
            )
        }
    }
}

@Composable
fun AdvancedTimePickerDialog(
    title: String = "Select Time",
    onDismiss: () -> Unit,
    onConfirm: () -> Unit,
    toggle: @Composable () -> Unit = {},
    content: @Composable () -> Unit,
) {
    Dialog(
        onDismissRequest = onDismiss,
        properties = DialogProperties(usePlatformDefaultWidth = false),
    ) {
        Surface(
            shape = MaterialTheme.shapes.extraLarge,
            tonalElevation = 6.dp,
            modifier =
            Modifier
                .width(IntrinsicSize.Min)
                .height(IntrinsicSize.Min)
                .background(
                    shape = MaterialTheme.shapes.extraLarge,
                    color = MaterialTheme.colorScheme.surface
                ),
        ) {
            Column(
                modifier = Modifier.padding(24.dp),
                horizontalAlignment = Alignment.CenterHorizontally
            ) {
                Text(
                    modifier = Modifier
                        .fillMaxWidth()
                        .padding(bottom = 20.dp),
                    text = title,
                    style = MaterialTheme.typography.labelMedium
                )
                content()
                Row(
                    modifier = Modifier
                        .height(40.dp)
                        .fillMaxWidth()
                ) {
                    toggle()
                    Spacer(modifier = Modifier.weight(1f))
                    TextButton(onClick = onDismiss) { Text("Cancel") }
                    TextButton(onClick = onConfirm) { Text("OK") }
                }
            }
        }
    }
}

Tieni presente i punti chiave di questo snippet:

  1. Il composable AdvancedTimePickerExample crea una finestra di dialogo di selezione dell'ora personalizzabile.
  2. Utilizza un componibile Dialog per una maggiore flessibilità rispetto a AlertDialog.
  3. La finestra di dialogo include un titolo personalizzabile e un pulsante di attivazione/disattivazione per passare tra la modalità di selezione e quella di immissione.
  4. Surface applica la forma e l'elevazione alla finestra di dialogo, con IntrinsicSize.Min sia per la larghezza che per l'altezza.
  5. Il layout Column e Row fornisce i componenti della struttura della finestra di dialogo.
  6. L'esempio monitora la modalità del selettore utilizzando showDial.
    • Un IconButton consente di passare da una modalità all'altra, aggiornando l'icona di conseguenza.
    • I contenuti della finestra di dialogo passano da TimePicker a TimeInput in base allo stato showDial.

Questa implementazione avanzata fornisce una finestra di dialogo per la selezione dell'ora altamente personalizzabile e riutilizzabile che può adattarsi a diversi casi d'uso nella tua app.

Questa implementazione è visualizzata come segue:

Un selettore dell'ora in una finestra di dialogo personalizzata che implementa un titolo, un pulsante di attivazione/disattivazione della modalità e pulsanti di chiusura e conferma.
Figura 2. Un selettore dell'ora in una finestra di dialogo personalizzata.

Risorse aggiuntive