בוררי תאריכים מאפשרים למשתמשים לבחור תאריך, טווח תאריכים או את שניהם. הם משתמשים בתיבת דו-שיח של יומן או בהזנת טקסט כדי לאפשר למשתמשים לבחור תאריכים.
סוגים
יש שלושה סוגים של כלי לבחירת תאריך:
- בעגינה: מופיע בתוך הפריסה. הוא מתאים לפריסות קומפקטיות שבהן תיבת דו-שיח ייעודית עלולה להפריע.
- חלון מודאלי: מופיע כתיבת דו-שיח שמוצגת מעל התוכן של האפליקציה. כך אפשר להתמקד בבחירת התאריך.
- קלט במודל: שילוב של שדה טקסט עם בוחר תאריכים במודל.
אפשר להטמיע את כלי הבחירה של התאריכים באפליקציה באמצעות רכיבי ה-Composable הבאים:
-
DatePicker
: רכיב כללי שאפשר להשתמש בו כדי ליצור רכיב לבחירת תאריך. המכל שבו משתמשים קובע אם הוא מעוגן או מודל. -
DatePickerDialog
: הקונטיינר של בחירת תאריך בתיבת דו-שיח ושל בחירת תאריך בתיבת דו-שיח עם שדה קלט. -
DateRangePicker
: לכל חלונית לבחירת תאריך שבה המשתמש יכול לבחור טווח עם תאריך התחלה ותאריך סיום.
מדינה
פרמטר המפתח שמשותף לכל רכיבי ה-Composable של בחירת התאריכים הוא state
, שמקבל אובייקט DatePickerState
או DateRangePickerState
. המאפיינים שלהם מתעדים מידע על הבחירה של המשתמש באמצעות הכלי לבחירת תאריכים, כמו התאריך הנוכחי שנבחר.
מידע נוסף על אופן השימוש בתאריך שנבחר זמין בקטע שימוש בתאריך שנבחר.
החלונית לבחירת תאריך מעוגנת
בדוגמה הבאה, יש שדה טקסט שמבקש מהמשתמש להזין את תאריך הלידה שלו. כשלוחצים על סמל היומן בשדה, נפתח בורר תאריכים מעוגן מתחת לשדה הקלט.
@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)) }
נקודות עיקריות לגבי הקוד
- הכלי לבחירת תאריך מופיע כשהמשתמש לוחץ על
IconButton
.- לחצן הסמל משמש כארגומנט לפרמטר
OutlinedTextField
'strailingIcon
. - משתנה המצב
showDatePicker
קובע את החשיפה של הכלי לבחירת תאריך שעוגן.
- לחצן הסמל משמש כארגומנט לפרמטר
- המאגר של בוחר התאריכים הוא
Popup
שאפשר להרכיב, והוא מוצג כשכבת-על מעל התוכן בלי להשפיע על הפריסה של רכיבים אחרים. -
selectedDate
מחלץ את הערך של התאריך שנבחר מהאובייקטDatePickerState
ומעצב אותו באמצעות הפונקציהconvertMillisToDate
. - התאריך שנבחר מופיע בשדה הטקסט.
- בוחר התאריכים המעוגן ממוקם מתחת לשדה הטקסט באמצעות משנה
offset
. - התג
Box
משמש כמאגר הבסיס כדי לאפשר שכבות מתאימות של שדה הטקסט ושל הכלי לבחירת תאריך.
תוצאות
אחרי שלוחצים על סמל היומן, ההטמעה הזו מופיעה כך:

חלונית מודאלית לבחירת תאריך
כלי לבחירת תאריך במצב מודאלי מציג תיבת דו-שיח שצפה מעל המסך. כדי להטמיע אותו, יוצרים DatePickerDialog
ומעבירים לו 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) } }
נקודות עיקריות לגבי הקוד
- הפונקציה הניתנת להגדרה
DatePickerModal
מציגה חלונית מודאלית לבחירת תאריך. - ביטוי ה-lambda
onDateSelected
מופעל כשהמשתמש בוחר תאריך.- הוא חושף את התאריך שנבחר לרכיב ההורה הניתן להרכבה.
- ביטוי ה-lambda
onDismiss
מופעל כשהמשתמש סוגר את תיבת הדו-שיח.
תוצאות
ההטמעה הזו נראית כך:

הזנת תאריך בחלונית לבחירת תאריך
לוח שנה מודאלי לבחירת תאריך עם שדה קלט מציג תיבת דו-שיח שמופיעה מעל המסך ומאפשרת למשתמש להזין תאריך.
@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) } }
נקודות עיקריות לגבי הקוד
הדוגמה הזו דומה מאוד לדוגמה של חלונית לבחירת תאריך. ההבדל העיקרי הוא:
- הפרמטר
initialDisplayMode
מגדיר את מצב התצוגה הראשוני ל-DisplayMode.Input
.

חלונית לבחירת תאריך עם טווח
אפשר ליצור חלונית לבחירת תאריך שמאפשרת למשתמש לבחור טווח בין תאריך התחלה לתאריך סיום. כדי לעשות את זה, משתמשים בפקודה DateRangePicker
.
השימוש ב-DateRangePicker
זהה בעצם לשימוש ב-DatePicker
. אפשר להשתמש בו כבוחר צבעים מעוגן כרכיב צאצא של PopUp
, או להשתמש בו כבוחר צבעים מודאלי ולהעביר אותו אל DatePickerDialog
. ההבדל העיקרי הוא שבמקום DatePickerState
, משתמשים ב-DateRangePickerState
.
בדוגמה הבאה אפשר לראות איך יוצרים בוחר תאריכים מודאלי עם טווח:
@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) ) } }
נקודות עיקריות לגבי הקוד
- הפרמטר
onDateRangeSelected
הוא קריאה חוזרת שמקבלתPair<Long?, Long?>
שמייצג את תאריכי ההתחלה והסיום שנבחרו. כך ההורה מקבל גישה להרכבה לטווח שנבחר. -
rememberDateRangePickerState()
יוצר את המצב של הכלי לבחירת טווח תאריכים. - התג
DatePickerDialog
יוצר מאגר של תיבת דו-שיח מודאלית. - ב-handler של לחצן האישור
onClick
, הפונקציהonDateRangeSelected
מעבירה את הטווח שנבחר אל ה-composable של ההורה. - רכיב ה-Composable
DateRangePicker
משמש כתוכן של תיבת הדו-שיח.
תוצאות
ההטמעה הזו נראית כך:

שימוש בתאריך שנבחר
כדי לתעד את התאריך שנבחר, עוקבים אחריו בקומפוזיציה הראשית כ-Long
ומעבירים את הערך אל DatePicker
ב-onDateSelected
. קטע הקוד הבא ממחיש את זה, אבל אפשר לראות את ההטמעה המלאה באפליקציית קטעי הקוד הרשמית.
// ... 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 } ) } // ...
אותו הדבר נכון גם לגבי כלי לבחירת תאריכים בטווח, אבל צריך להשתמש ב-Pair<Long?, Long?>
או בסוג נתונים כדי לתעד את ערכי ההתחלה והסיום.