Mit Datumsauswahlen können Nutzer ein Datum, einen Zeitraum oder beides auswählen. Sie verwenden ein Kalenderdialogfeld oder eine Texteingabe, damit Nutzer Termine auswählen können.
Typen
Es gibt drei Arten von Datumsauswahlen:
- Angedockt: Wird innerhalb des Layouts Inline angezeigt. Sie eignet sich für kompakte Layouts, in denen ein spezielles Dialogfeld aufdringlich wirken könnte.
- Modal: Wird als Dialogfeld über den App-Inhalten angezeigt. So wird der Fokus auf die Datumsauswahl gelenkt.
- Modale Eingabe: Hier wird ein Textfeld mit einer modalen Datumsauswahl kombiniert.
Sie können diese Datumsauswahlen mit den folgenden Composeables in Ihrer App implementieren:
DatePicker
: Allgemeines Composeable für eine Datumsauswahl. Je nach Container wird das Gerät angedockt oder als Modell angezeigt.DatePickerDialog
: Der Container für modale und modale Eingabe-Datumsauswahlen.DateRangePicker
: Für jede Datumsauswahl, in der Nutzer einen Zeitraum mit Start- und Enddatum auswählen können.
Bundesland
Der wichtigste Parameter, den die verschiedenen Datumsauswahl-Kompositionen gemeinsam haben, ist state
. Er kann entweder ein DatePickerState
- oder ein DateRangePickerState
-Objekt annehmen. Mit ihren Properties werden Informationen zur Auswahl des Nutzers mithilfe der Datumsauswahl erfasst, z. B. das aktuell ausgewählte Datum.
Weitere Informationen dazu, wie Sie das ausgewählte Datum verwenden können, finden Sie im Abschnitt Ausgewähltes Datum verwenden.
Angedockte Datumsauswahl
Im folgenden Beispiel wird der Nutzer in einem Textfeld aufgefordert, sein Geburtsdatum einzugeben. Wenn der Nutzer auf das Kalendersymbol im Feld klickt, wird unter dem Eingabefeld eine angedockte Datumsauswahl geöffnet.
@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 ) } } } } } @Composable fun DatePickerFieldToModal(modifier: Modifier = Modifier) { var selectedDate by remember { mutableStateOf<Long?>(null) } var showModal by remember { mutableStateOf(false) } OutlinedTextField( value = selectedDate?.let { convertMillisToDate(it) } ?: "", onValueChange = { }, label = { Text("DOB") }, placeholder = { Text("MM/DD/YYYY") }, trailingIcon = { Icon(Icons.Default.DateRange, contentDescription = "Select date") }, modifier = modifier .fillMaxWidth() .pointerInput(selectedDate) { awaitEachGesture { // Modifier.clickable doesn't work for text fields, so we use Modifier.pointerInput // in the Initial pass to observe events before the text field consumes them // in the Main pass. awaitFirstDown(pass = PointerEventPass.Initial) val upEvent = waitForUpOrCancellation(pass = PointerEventPass.Initial) if (upEvent != null) { showModal = true } } } ) if (showModal) { DatePickerModal( onDateSelected = { selectedDate = it }, onDismiss = { showModal = false } ) } } fun convertMillisToDate(millis: Long): String { val formatter = SimpleDateFormat("MM/dd/yyyy", Locale.getDefault()) return formatter.format(Date(millis)) }
Wichtige Punkte zum Code
- Die Datumsauswahl wird angezeigt, wenn der Nutzer auf
IconButton
klickt.- Die Symbolschaltfläche dient als Argument für den
trailingIcon
-Parameter vonOutlinedTextField
. - Mit der Statusvariablen
showDatePicker
wird die Sichtbarkeit der angedockten Datumsauswahl gesteuert.
- Die Symbolschaltfläche dient als Argument für den
- Der Container der Datumsauswahl ist ein
Popup
-kompositbares Element, das den Inhalt überlagert, ohne das Layout anderer Elemente zu beeinträchtigen. selectedDate
erfasst den Wert des ausgewählten Datums aus demDatePickerState
-Objekt und formatiert ihn mit derconvertMillisToDate
-Funktion.- Das ausgewählte Datum wird im Textfeld angezeigt.
- Die angedockte Datumsauswahl wird mit einem
offset
-Modifikator unter dem Textfeld positioniert. - Ein
Box
wird als Stammcontainer verwendet, um das Textfeld und die Datumsauswahl richtig zu schichten.
Ergebnisse
Nach dem Klicken auf das Kalendersymbol sieht diese Implementierung so aus:
Modale Datumsauswahl
Eine modale Datumsauswahl zeigt ein Dialogfeld an, das über dem Bildschirm schwebt. Erstellen Sie dazu eine DatePickerDialog
und übergeben Sie ihr eine 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) } }
Wichtige Punkte zum Code
- Die zusammensetzbare Funktion
DatePickerModal
zeigt eine modale Datumsauswahl an. - Der Lambda-Ausdruck
onDateSelected
wird ausgeführt, wenn der Nutzer ein Datum auswählt.- Das ausgewählte Datum wird dem übergeordneten Composeable-Element zur Verfügung gestellt.
- Der Lambda-Ausdruck
onDismiss
wird ausgeführt, wenn der Nutzer den Dialog schließt.
Ergebnisse
Diese Implementierung sieht so aus:
Modale Datumsauswahl
Eine modale Datumsauswahl mit Eingabefeld blendet ein Dialogfeld über dem Bildschirm ein, in dem der Nutzer ein Datum eingeben kann.
@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) } }
Wichtige Punkte zum Code
Das ist sehr ähnlich wie beim Beispiel für eine modale Datumsauswahl. Der Hauptunterschied besteht darin:
- Mit dem Parameter
initialDisplayMode
wird der anfängliche Anzeigemodus aufDisplayMode.Input
festgelegt.
Datumsauswahl mit Zeitraum
Sie können eine Datumsauswahl erstellen, mit der Nutzer einen Zeitraum zwischen einem Start- und einem Enddatum auswählen können. Verwenden Sie dazu DateRangePicker
.
Die Verwendung von DateRangePicker
entspricht im Wesentlichen der von DatePicker
. Sie können es als untergeordnetes Element von PopUp
für eine angedockte Auswahl oder als modale Auswahl verwenden und an DatePickerDialog
übergeben. Der Hauptunterschied besteht darin, dass Sie DateRangePickerState
anstelle von DatePickerState
verwenden.
Im folgenden Snippet wird gezeigt, wie eine modale Datumsauswahl mit einem Bereich erstellt wird:
@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) ) } }
Wichtige Punkte zum Code
- Der Parameter
onDateRangeSelected
ist ein Rückruf, der einenPair<Long?, Long?>
empfängt, der die ausgewählten Start- und Enddaten darstellt. Dadurch erhält das übergeordnete Element Zugriff auf den ausgewählten Bereich. rememberDateRangePickerState()
erstellt den Status für die Auswahl des Zeitraums.- Mit
DatePickerDialog
wird ein modaler Dialogfeldcontainer erstellt. - Im
onClick
-Handler der Bestätigungsschaltfläche gibtonDateRangeSelected
den ausgewählten Bereich an das übergeordnete Composeable weiter. - Das
DateRangePicker
-Komposit dient als Dialoginhalt.
Ergebnisse
Diese Implementierung sieht so aus:
Ausgewähltes Datum verwenden
Wenn Sie das ausgewählte Datum erfassen möchten, erfassen Sie es im übergeordneten Composeable als Long
und übergeben Sie den Wert an die DatePicker
in onDateSelected
. Das folgende Snippet veranschaulicht dies. Die vollständige Implementierung finden Sie in der offiziellen Snippets App.
// ... 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 } ) } // ...
Im Wesentlichen gilt das Gleiche für Datumsauswahlen für Bereiche. Sie müssen jedoch eine Pair<Long?, Long?>
oder eine Datenklasse verwenden, um die Start- und Endwerte zu erfassen.