Selettori della data

I selettori della data consentono agli utenti di selezionare una data, un intervallo di date o entrambi. Utilizzano un finestra di dialogo del calendario o input di testo per consentire agli utenti di selezionare le date.

Tipi

Esistono tre tipi di selettori della data:

  • Ancorata: viene visualizzata in linea all'interno del layout. È adatto a dispositivi compatti layout in cui una finestra di dialogo dedicata potrebbe sembrare invadente.
  • Modale: viene visualizzata come una finestra di dialogo che si sovrappone ai contenuti dell'app. Ciò fornisce un cancella lo stato attivo sulla selezione della data.
  • Input modale: combina un campo di testo con un selettore della data modale.

Puoi implementare questi selettori della data nella tua app utilizzando: componibili:

  • DatePicker: componibile generale per un selettore di date. Il container determina se agganciato alla base o modello.
  • DatePickerDialog: il contenitore della data di input modale e modale. selettori.
  • DateRangePicker: per qualsiasi selettore di date in cui l'utente può selezionare una data con una data di inizio e una di fine.
di Gemini Advanced.

Stato

Il parametro chiave che i diversi componenti componibili del selettore della data condividono in comune è state, che richiede DatePickerState oppure DateRangePickerState. Le loro proprietà acquisiscono informazioni la selezione dell'utente usando il selettore della data, ad esempio la data corrente selezionata.

Per ulteriori informazioni su come utilizzare la data selezionata, consulta la sezione Utilizza sezione data selezionata.

Selettore della data ancorato

Nell'esempio seguente, è presente un campo di testo che richiede all'utente di inserire la data di nascita. Quando fanno clic sull'icona del calendario nel campo, si apre una selettore della data agganciata sotto il campo di immissione.

@Composable
fun DatePickerDocked() {
    var showDatePicker by remember { mutableStateOf(false) }
    val datePickerState = rememberDatePickerState()
    val selectedDate = datePickerState.selectedDateMillis?.let {
        convertMillisToDate(it)
    } ?: ""

    Box(
        modifier = Modifier.fillMaxWidth()
    ) {
        OutlinedTextField(
            value = selectedDate,
            onValueChange = { },
            label = { Text("DOB") },
            readOnly = true,
            trailingIcon = {
                IconButton(onClick = { showDatePicker = !showDatePicker }) {
                    Icon(
                        imageVector = Icons.Default.DateRange,
                        contentDescription = "Select date"
                    )
                }
            },
            modifier = Modifier
                .fillMaxWidth()
                .height(64.dp)
        )

        if (showDatePicker) {
            Popup(
                onDismissRequest = { showDatePicker = false },
                alignment = Alignment.TopStart
            ) {
                Box(
                    modifier = Modifier
                        .fillMaxWidth()
                        .offset(y = 64.dp)
                        .shadow(elevation = 4.dp)
                        .background(MaterialTheme.colorScheme.surface)
                        .padding(16.dp)
                ) {
                    DatePicker(
                        state = datePickerState,
                        showModeToggle = false
                    )
                }
            }
        }
    }
}

fun convertMillisToDate(millis: Long): String {
    val formatter = SimpleDateFormat("MM/dd/yyyy", Locale.getDefault())
    return formatter.format(Date(millis))
}

Punti chiave sul codice

  • Il selettore della data viene visualizzato quando l'utente fa clic sulla IconButton.
    • Il pulsante icona funge da argomento per gli elementi OutlinedTextField trailingIcon.
    • La variabile di stato showDatePicker controlla la visibilità selettore data agganciato.
  • Il contenitore del selettore della data è un componibile Popup, che si sovrappone alla senza alterare il layout di altri elementi.
  • selectedDate acquisisce il valore della data selezionata nel DatePickerState e lo formatta utilizzando l'oggetto convertMillisToDate personalizzata.
  • La data selezionata viene visualizzata nel campo di testo.
  • Il selettore della data agganciato alla base si trova sotto il campo di testo utilizzando un offset modificatore.
  • Un Box viene utilizzato come container principale per consentire la corretta sovrapposizione del testo e il selettore della data.

Risultati

Dopo aver fatto clic sull'icona del calendario, l'implementazione appare come segue:

Esempio di selettore della data agganciato.
Figura 1. Un selettore della data agganciato.

Un selettore di date modale mostra una finestra di dialogo che fluttua sullo schermo. Per implementare crea una DatePickerDialog e passala a DatePicker.

@Composable
fun DatePickerModal(
    onDateSelected: (Long?) -> Unit,
    onDismiss: () -> Unit
) {
    val datePickerState = rememberDatePickerState()

    DatePickerDialog(
        onDismissRequest = onDismiss,
        confirmButton = {
            TextButton(onClick = {
                onDateSelected(datePickerState.selectedDateMillis)
                onDismiss()
            }) {
                Text("OK")
            }
        },
        dismissButton = {
            TextButton(onClick = onDismiss) {
                Text("Cancel")
            }
        }
    ) {
        DatePicker(state = datePickerState)
    }
}

  • La funzione componibile DatePickerModal mostra un selettore di date modale.
  • L'espressione lambda onDateSelected viene eseguita quando l'utente seleziona una data.
    • Espone la data selezionata al componibile principale.
  • L'espressione lambda onDismiss viene eseguita quando l'utente ignora l'oggetto .

Risultati

Questa implementazione si presenta nel seguente modo:

Esempio di selettore della data modale.
Figura 2. Un selettore di date modale.

Selettore data modale di input

Un selettore di date modale con input mostra una finestra di dialogo che fluttua sullo schermo e permette all'utente di inserire una data.

@Composable
fun DatePickerModalInput(
    onDateSelected: (Long?) -> Unit,
    onDismiss: () -> Unit
) {
    val datePickerState = rememberDatePickerState(initialDisplayMode = DisplayMode.Input)

    DatePickerDialog(
        onDismissRequest = onDismiss,
        confirmButton = {
            TextButton(onClick = {
                onDateSelected(datePickerState.selectedDateMillis)
                onDismiss()
            }) {
                Text("OK")
            }
        },
        dismissButton = {
            TextButton(onClick = onDismiss) {
                Text("Cancel")
            }
        }
    ) {
        DatePicker(state = datePickerState)
    }
}

È molto simile all'esempio di selettore della data modale. Il principale è la seguente:

  • Il parametro initialDisplayMode imposta la modalità di visualizzazione iniziale su DisplayMode.Input.
di Gemini Advanced.
Selettore della data modale con input.
Figura 3. Un selettore di date modale con input.

Selettore della data con intervallo

Puoi creare un selettore di date che consente all'utente di scegliere un intervallo tra un inizio e data di fine. Per farlo, utilizza DateRangePicker.

L'utilizzo di DateRangePicker è sostanzialmente lo stesso di DatePicker. Puoi da utilizzare per un selettore agganciato all'elemento secondario di PopUp oppure come selettore modale e passalo a DatePickerDialog. La differenza principale è che utilizzi DateRangePickerState anziché DatePickerState.

Il seguente snippet mostra come creare un selettore di date modale con un intervallo:

@Composable
fun DateRangePickerModal(
    onDateRangeSelected: (Pair<Long?, Long?>) -> Unit,
    onDismiss: () -> Unit
) {
    val dateRangePickerState = rememberDateRangePickerState()

    DatePickerDialog(
        onDismissRequest = onDismiss,
        confirmButton = {
            TextButton(
                onClick = {
                    onDateRangeSelected(
                        Pair(
                            dateRangePickerState.selectedStartDateMillis,
                            dateRangePickerState.selectedEndDateMillis
                        )
                    )
                    onDismiss()
                }
            ) {
                Text("OK")
            }
        },
        dismissButton = {
            TextButton(onClick = onDismiss) {
                Text("Cancel")
            }
        }
    ) {
        DateRangePicker(
            state = dateRangePickerState,
            title = {
                Text(
                    text = "Select date range"
                )
            },
            showModeToggle = false,
            modifier = Modifier
                .fillMaxWidth()
                .height(500.dp)
                .padding(16.dp)
        )
    }
}

Punti chiave sul codice

  • Il parametro onDateRangeSelected è un callback che riceve un Pair<Long?, Long?> che rappresenta le date di inizio e di fine selezionate. Questo concede all'elemento componibile padre l'accesso all'intervallo selezionato.
  • rememberDateRangePickerState() crea lo stato per l'intervallo di date selettore.
  • L'DatePickerDialog crea un contenitore di finestra di dialogo modale.
  • Nel gestore onClick del pulsante di conferma, onDateRangeSelected rinuncia l'intervallo selezionato al componibile padre.
  • L'elemento componibile DateRangePicker funge da contenuto della finestra di dialogo.

Risultati

Questa implementazione si presenta nel seguente modo:

Esempio di selettore di date dell&#39;intervallo modale.
Figura 4. Un selettore di date modale con un intervallo selezionato.

Usa data selezionata

Per acquisire la data selezionata, monitorala nel componibile principale come Long e passa il valore a DatePicker in onDateSelected. Il seguente snippet lo dimostra, anche se si può vedere l'implementazione completa nel di snippet.

// ...
    var selectedDate by remember { mutableStateOf<Long?>(null) }
// ...
        if (selectedDate != null) {
            val date = Date(selectedDate!!)
            val formattedDate = SimpleDateFormat("MMM dd, yyyy", Locale.getDefault()).format(date)
            Text("Selected date: $formattedDate")
        } else {
            Text("No date selected")
        }
// ...
        DatePickerModal(
            onDateSelected = {
                selectedDate = it
                showModal = false
            },
            onDismiss = { showModal = false }
        )
    }
// ...

Essenzialmente lo stesso vale per i selettori dell'intervallo di date, anche se devi utilizza un Pair<Long?, Long?> o una classe di dati per acquisire i valori di inizio e fine.

Vedi anche