انتخابگرهای تاریخ به کاربران امکان میدهند تاریخ، محدوده تاریخ، یا هر دو را انتخاب کنند. آنها از کادر گفتگوی تقویم یا ورودی نوشتاری استفاده میکنند تا به کاربران امکان دهند تاریخها را انتخاب کنند.
انواع
سه نوع انتخابگر تاریخ وجود دارد:
- متصل به پایه: بهصورت درونخطی در چیدمان ظاهر میشود. این گزینه برای چیدمانهای فشرده مناسب است، جایی که یک کادر گفتگوی اختصاصی ممکن است مزاحم بهنظر برسد.
- کیفیتی: بهصورت کادر گفتگویی ظاهر میشود که روی محتوای برنامه قرار میگیرد. این کار تمرکز واضحی روی انتخاب تاریخ فراهم میکند.
- ورودی مدال: فیلد نوشتاری را با انتخابگر تاریخ مدال ترکیب میکند.
میتوانید این انتخابگرهای تاریخ را بااستفاده از ترکیبپذیرهای زیر در برنامهتان پیادهسازی کنید:
DatePicker: ترکیبپذیر عمومی برای انتخابگر تاریخ. ظرفی که استفاده میکنید تعیین میکند که آیا ثابت است یا مدل.DatePickerDialog: محفظه برای هر دو انتخابگر تاریخ ورودی وجهی و وجهی.DateRangePicker: برای هر انتخابگر تاریخی که کاربر میتواند محدودهای با تاریخ شروع و پایان انتخاب کند.
ایالت
پارامتر کلیدی که ترکیبپذیرهای مختلف انتخابگر تاریخ بهطور مشترک دارند
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کلیک میکند، انتخابگر تاریخ ظاهر میشود.- دکمه نماد بهعنوان آرگومان برای پارامتر
trailingIconOutlinedTextFieldعمل میکند. - متغیر حالت
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یک انتخابگر تاریخ مُدال را نمایش میدهد. - عبارت لامبدا
onDateSelectedزمانی اجرا میشود که کاربر تاریخی را انتخاب کند.- تاریخ انتخابشده را درمعرض ترکیبپذیر والد قرار میدهد.
- عبارت لامبدا
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یک callback است که یک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", LocalLocale.current.platformLocale).format(date) Text("Selected date: $formattedDate") } else { Text("No date selected") } // ... DatePickerModal( onDateSelected = { selectedDate = it showModal = false }, onDismiss = { showModal = false } ) } // ...
اساساً همین موضوع برای انتخابکنندههای تاریخ محدوده نیز صدق میکند، هرچند باید
از Pair<Long?, Long?> یا کلاس داده برای ثبت مقادیر شروع و پایان استفاده کنید.