Sélecteurs de date

Les sélecteurs de dates permettent aux utilisateurs de sélectionner une date, une plage de dates ou les deux. Il utilise un boîte de dialogue de calendrier ou saisie de texte pour permettre aux utilisateurs de sélectionner des dates.

Types

Il existe trois types de sélecteurs de date:

  • Ancrée: apparaît de manière intégrée dans la mise en page. Il convient aux formats compacts mises en page où une boîte de dialogue dédiée peut sembler intrusive.
  • Modal: s'affiche sous la forme d'une boîte de dialogue superposée au contenu de l'application. Vous bénéficiez ainsi d'une le curseur sur la sélection de la date.
  • Saisie modale: combine un champ de texte avec un sélecteur de date modal.

Vous pouvez implémenter ces sélecteurs de date dans votre application à l'aide des éléments suivants : composables:

  • DatePicker: composable général pour un sélecteur de date. Le conteneur que vous « use » détermine s'il est « posé sur la station d'accueil » ou s'il est modélisé.
  • DatePickerDialog: conteneur de la date de saisie modale et modale des outils de sélection.
  • DateRangePicker: pour tout sélecteur de date où l'utilisateur peut choisir une avec une date de début et une date de fin.

État

Le paramètre clé que les différents composables du sélecteur de date partagent en commun est state, qui accepte un DatePickerState ou DateRangePickerState. Leurs propriétés retiennent des informations sur la sélection de l'utilisateur à l'aide du sélecteur de date (la date actuellement sélectionnée, par exemple) ;

Pour plus d'informations sur la façon d'utiliser la date sélectionnée, consultez la section Utiliser la section des dates sélectionnées.

Sélecteur de date ancré

L'exemple suivant montre un champ de texte qui invite l'utilisateur à saisir leur date de naissance. Lorsque l'utilisateur clique sur l'icône du calendrier dans le champ, sélecteur de date ancré sous le champ de saisie.

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

Points clés concernant le code

  • Le sélecteur de date s'affiche lorsque l'utilisateur clique sur IconButton.
    • Le bouton d'icône sert d'argument pour l'objet OutlinedTextField Paramètre trailingIcon.
    • La variable d'état showDatePicker contrôle la visibilité sélecteur de date ancré.
  • Le conteneur du sélecteur de date est un composable Popup, qui se superpose aux le contenu sans affecter la mise en page des autres éléments.
  • selectedDate capture la valeur de la date sélectionnée à partir de l'objet DatePickerState et le met en forme à l'aide de convertMillisToDate. .
  • La date sélectionnée apparaît dans le champ de texte.
  • Le sélecteur de date ancré est positionné sous le champ de texte à l'aide d'un offset. modificateur.
  • Un Box est utilisé comme conteneur racine pour permettre une superposition correcte du texte. et le sélecteur de date.

Résultats

Une fois que vous avez cliqué sur l'icône de calendrier, cette implémentation se présente comme suit:

Exemple de sélecteur de date ancré.
Figure 1. Sélecteur de date ancré.

Un sélecteur de date modal affiche une boîte de dialogue qui flotte au-dessus de l'écran. Pour implémenter créez un DatePickerDialog et transmettez-lui un 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 fonction composable DatePickerModal affiche un sélecteur de date modal.
  • L'expression lambda onDateSelected s'exécute lorsque l'utilisateur sélectionne un la date de début.
    • Il expose la date sélectionnée au composable parent.
  • L'expression lambda onDismiss s'exécute lorsque l'utilisateur ignore l'objet .

Résultats

Cette implémentation est la suivante :

Exemple de sélecteur de date modal.
Figure 2. Un sélecteur de date modal.

Sélecteur modal de saisie de la date

Un sélecteur de date modal avec entrée affiche une boîte de dialogue qui flotte au-dessus de l'écran et permet à l'utilisateur de saisir une date.

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

Cette méthode est très semblable à l'exemple de sélecteur de date modal. L'instance principale est la suivante:

  • Le paramètre initialDisplayMode définit le mode d'affichage initial sur DisplayMode.Input
Sélecteur de date modal avec entrée.
Figure 3. Sélecteur de date modal avec entrée.

Sélecteur de date avec plage

Vous pouvez créer un sélecteur de date qui permet à l'utilisateur de sélectionner une période entre la date de début et la date de fin. Pour ce faire, utilisez DateRangePicker.

L'utilisation de DateRangePicker est essentiellement la même que DatePicker. Vous pouvez Utilisez-le pour un sélecteur ancré en tant qu'enfant de PopUp, ou utilisez-le en tant que sélecteur modal et transmettez-le à DatePickerDialog. La principale différence est que vous utilisez DateRangePickerState au lieu de DatePickerState.

L'extrait de code suivant montre comment créer un sélecteur de date modal avec une plage:

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

Points clés concernant le code

  • Le paramètre onDateRangeSelected est un rappel qui reçoit une Pair<Long?, Long?> représentant les dates de début et de fin sélectionnées. Ce permet au composable parent d'accéder à la plage sélectionnée.
  • rememberDateRangePickerState() crée l'état pour la plage de dates sélecteur.
  • DatePickerDialog crée un conteneur de boîte de dialogue modal.
  • Dans le gestionnaire onClick du bouton de confirmation, onDateRangeSelected transmet la plage sélectionnée au composable parent.
  • Le composable DateRangePicker sert de contenu de boîte de dialogue.

Résultats

Cette implémentation est la suivante :

Exemple de sélecteur de date par plage modale.
Figure 4. Outil de sélection de date modal avec une plage sélectionnée

Utiliser la date sélectionnée

Pour capturer la date sélectionnée, suivez-la dans le composable parent en tant que Long et transmettez la valeur à DatePicker dans onDateSelected. L'extrait suivant le démontre. Vous pouvez toutefois voir l'implémentation complète dans le document officiel application d'extraits de code.

// ...
    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 }
        )
    }
// ...

Il en va de même pour les sélecteurs de dates, mais vous devez Utilisez un Pair<Long?, Long?> ou une classe de données pour capturer les valeurs de début et de fin.

Voir aussi