通过日期选择器,用户可以选择日期和/或日期范围。他们使用 日历对话框或文本输入,以便用户选择日期。
类型
日期选择器有三种类型:
- 已固定:在布局中内嵌显示。它适用于 在布局中,专门的对话框可能会让人感觉有干扰。
- 模态:显示为叠加在应用内容的对话框。这提供了一个 明确选择日期。
- 模态输入:将文本字段与模态日期选择器组合使用。
您可以使用以下代码在应用中实现这些日期选择器 可组合项:
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 ) } } } } } fun convertMillisToDate(millis: Long): String { val formatter = SimpleDateFormat("MM/dd/yyyy", Locale.getDefault()) return formatter.format(Date(millis)) }
代码要点
- 当用户点击
IconButton
时,系统会显示日期选择器。- 图标按钮可用作
OutlinedTextField
的trailingIcon
参数。 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
lambda 表达式会在用户选择 日期。- 它会将所选日期公开给父级可组合项。
onDismiss
lambda 表达式会在用户关闭 对话框。
结果
此实现如下所示:
输入模态日期选择器
包含输入内容的模态日期选择器会显示一个对话框,该对话框悬浮在屏幕上,并且 允许用户输入日期。
@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
。主要区别在于
您使用的是 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) .padding(16.dp) ) } }
代码要点
onDateRangeSelected
参数是一个回调,用于接收表示所选开始日期和结束日期的Pair<Long?, Long?>
。这会授予父级可组合项对所选范围的访问权限。rememberDateRangePickerState()
用于创建日期范围的状态 选择器。DatePickerDialog
会创建一个模态对话框容器。- 在确认按钮的
onClick
处理程序中,onDateRangeSelected
会传递 传递给父级可组合项。 DateRangePicker
可组合项充当对话框内容。
结果
此实现如下所示:
使用所选日期
如需捕获所选日期,请在父级可组合项中将其作为 Long
进行跟踪,
将值传递给 onDateSelected
中的 DatePicker
。以下代码段
但您可以在官方
摘要应用。
// ... 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?>
或数据类来捕获开始值和结束值。