تتيح أدوات اختيار التاريخ للمستخدمين اختيار تاريخ أو نطاق زمني أو كليهما. تستخدم هذه الحقول مربّع حوار تقويم أو إدخال نصي للسماح للمستخدمين باختيار التواريخ.
الأنواع
هناك ثلاثة أنواع من أدوات اختيار التاريخ:
- مثبَّتة: تظهر مضمّنة في التنسيق. وهي مناسبة للتنسيقات المدمجة التي قد يبدو فيها مربّع الحوار المخصّص مزعجًا.
- النافذة المشروطة: تظهر كنافذة حوارية تتراكب على محتوى التطبيق. ويوفّر ذلك تركيزًا واضحًا على اختيار التاريخ.
- الإدخال المشروط: يجمع بين حقل نصي وأداة اختيار التاريخ المشروطة.
يمكنك تنفيذ أدوات اختيار التاريخ هذه في تطبيقك باستخدام العناصر القابلة للإنشاء التالية:
DatePicker: عنصر عام قابل للإنشاء لاختيار التاريخ. تحدّد الحاوية التي تستخدمها ما إذا كانت ثابتة أو نموذجية.-
DatePickerDialog: الحاوية الخاصة بكل من أدوات اختيار التاريخ في مربّع الحوار وأدوات اختيار التاريخ في مربّع الحوار الخاص بالإدخال. -
DateRangePicker: لأي أداة اختيار تاريخ يمكن للمستخدم من خلالها تحديد نطاق يتضمّن تاريخ بدء وتاريخ انتهاء.
الولاية
المَعلمة الأساسية التي تشترك فيها عناصر Date Picker القابلة للإنشاء المختلفة هي
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.- يعمل زر الرمز كمعلَمة للوسيط
OutlinedTextFieldtrailingIcon. - يتحكّم متغير الحالة
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 = date } }DatePickers.kt
نقاط أساسية حول الرمز
- تعرض الدالة القابلة للإنشاء
DatePickerModalأداة اختيار التاريخ مشروطة. - يتم تنفيذ تعبير دالة
onDateSelectedLambda عندما يختار المستخدم تاريخًا.- تعرض هذه السمة التاريخ المحدّد للعنصر القابل للإنشاء الرئيسي.
- يتم تنفيذ تعبير
onDismisslambda عندما يغلق المستخدم مربّع الحوار.
النتائج
تظهر عملية التنفيذ هذه على النحو التالي:
أداة اختيار التاريخ في النافذة المنبثقة
تعرض أداة اختيار التاريخ المشروطة التي تتضمّن حقل إدخال مربع حوار يظهر فوق الشاشة ويسمح للمستخدم بإدخال تاريخ.
@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 = date } }DatePickers.kt
نقاط أساسية حول الرمز
هذا المثال يشبه إلى حد كبير مثال أداة اختيار التاريخ المنبثقة. ويكمن الاختلاف الأساسي في ما يلي:
- تضبط المَعلمة
initialDisplayModeوضع العرض الأوّلي علىDisplayMode.Input.
أداة اختيار التاريخ مع نطاق
يمكنك إنشاء أداة اختيار تاريخ تتيح للمستخدم اختيار نطاق بين تاريخَي البدء والانتهاء. لإجراء ذلك، استخدِم DateRangePicker.
إنّ استخدام DateRangePicker هو نفسه استخدام DatePicker. يمكنك استخدامها كأداة اختيار ثابتة كعنصر تابع لـ PopUp، أو يمكنك استخدامها كأداة اختيار مشروطة وتمريرها إلى DatePickerDialog. ويكمن الاختلاف الأساسي في استخدام DateRangePickerState بدلاً من DatePickerState.
يوضّح المقتطف التالي كيفية إنشاء أداة اختيار تاريخ مشروطة بنطاق:
@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) .pa ) } }DatePickers.kt
نقاط أساسية حول الرمز
- المَعلمة
onDateRangeSelectedهي دالة ردّ تتلقّىPair<Long?, Long?>يمثّل تاريخَي البدء والانتهاء المحدّدين. يمنح ذلك العنصر القابل للإنشاء الرئيسي إذن الوصول إلى النطاق المحدّد. - تنشئ السمة
rememberDateRangePickerState()حالة أداة اختيار النطاق الزمني. - ينشئ
DatePickerDialogحاوية مربّع حوار مشروط. - في معالج
onClickلزر التأكيد، تمرِّر الدالةonDateRangeSelectedالنطاق المحدّد إلى العنصر القابل للإنشاء الرئيسي. - يعمل العنصر القابل للإنشاء
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 = ) } // ...DatePickers.kt
وينطبق الأمر نفسه بشكل أساسي على أدوات اختيار التاريخ في النطاق، ولكن عليك استخدام Pair<Long?, Long?> أو فئة بيانات لالتقاط قيمتَي البدء والانتهاء.