انتخابگرهای تاریخ به کاربران امکان میدهند تاریخ، محدوده تاریخ، یا هر دو را انتخاب کنند. آنها از کادر گفتگوی تقویم یا ورودی نوشتاری استفاده میکنند تا به کاربران اجازه دهند تاریخها را انتخاب کنند.
انواع
سه نوع انتخابگر تاریخ وجود دارد:
- متصل به پایه: بهصورت درونخطی در چیدمان ظاهر میشود. این عنصر برای چیدمانهای فشرده مناسب است، جایی که یک کادر گفتگوی اختصاصی ممکن است مزاحم به نظر برسد.
- مدال: بهصورت کادر گفتگویی ظاهر میشود که روی محتوای برنامه قرار میگیرد. این کار تمرکز واضحی بر انتخاب تاریخ فراهم میکند.
- ورودی مدال: فیلد نوشتاری را با تاریخچین مدال ترکیب میکند.
میتوانید این انتخابگرهای تاریخ را بااستفاده از ترکیبپذیرهای زیر در برنامهتان پیادهسازی کنید:
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یک فراخوانی است کهPair<Long?, Long?>را دریافت میکند که نشاندهنده تاریخهای شروع و پایان انتخابشده است. این به ولی دسترسی قابلساخت به محدوده انتخابشده میدهد. -
rememberDateRangePickerState()وضعیت را برای انتخابگر محدوده تاریخ ایجاد میکند. DatePickerDialogمحفظه کادر گفتگوی مدال ایجاد میکند.- در گرداننده
onClickدکمه تأیید،onDateRangeSelectedمحدوده انتخابشده را به ترکیبپذیر والد منتقل میکند. DateRangePickercomposable بهعنوان محتوای کادر گفتگو عمل میکند.
نتایج
این پیادهسازی بهصورت زیر نشان داده میشود:
استفاده از تاریخ انتخابشده
برای ضبط تاریخ انتخابشده، آن را در ترکیبپذیر والد بهعنوان 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?> یا کلاس داده برای ثبت مقادیر شروع و پایان استفاده کنید.