Средства выбора дат позволяют пользователям выбирать дату, диапазон дат или и то, и другое. Они используют диалоговое окно календаря или ввод текста, чтобы пользователи могли выбирать даты.
Типы
Существует три типа выбора даты:
- Закреплено : отображается внутри макета. Он подходит для компактных макетов, где выделенный диалог может показаться навязчивым.
- Модальное окно : отображается в виде диалогового окна, накладывающего содержимое приложения. Это обеспечивает четкую фокусировку на выборе даты.
- Модальный ввод : объединяет текстовое поле с модальным выбором даты.
Вы можете реализовать эти средства выбора дат в своем приложении, используя следующие составные элементы:
-
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
.- Кнопка со значком служит аргументом для параметра
trailingIcon
OutlinedTextField
. - Переменная состояния
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
. Основное отличие состоит в том, что вы используете 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
и передайте значение 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?>
или класс данных для захвата начального и конечного значений.
См. также
,Средства выбора дат позволяют пользователям выбирать дату, диапазон дат или и то, и другое. Они используют диалоговое окно календаря или ввод текста, чтобы пользователи могли выбирать даты.
Типы
Существует три типа выбора даты:
- Закреплено : отображается внутри макета. Он подходит для компактных макетов, где выделенный диалог может показаться навязчивым.
- Модальное окно : отображается в виде диалогового окна, накладывающего содержимое приложения. Это обеспечивает четкую фокусировку на выборе даты.
- Модальный ввод : объединяет текстовое поле с модальным выбором даты.
Вы можете реализовать эти средства выбора дат в своем приложении, используя следующие составные элементы:
-
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
.- Кнопка со значком служит аргументом для параметра
trailingIcon
OutlinedTextField
. - Переменная состояния
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
. Основное отличие состоит в том, что вы используете 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
и передайте значение 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?>
или класс данных для захвата начального и конечного значений.
См. также
,Средства выбора дат позволяют пользователям выбирать дату, диапазон дат или и то, и другое. Они используют диалоговое окно календаря или ввод текста, чтобы пользователи могли выбирать даты.
Типы
Существует три типа выбора даты:
- Закреплено : отображается внутри макета. Он подходит для компактных макетов, где выделенный диалог может показаться навязчивым.
- Модальное окно : отображается в виде диалогового окна, накладывающего содержимое приложения. Это обеспечивает четкую фокусировку на выборе даты.
- Модальный ввод : объединяет текстовое поле с модальным выбором даты.
Вы можете реализовать эти средства выбора дат в своем приложении, используя следующие составные элементы:
-
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
.- Кнопка со значком служит аргументом для параметра
trailingIcon
OutlinedTextField
. - Переменная состояния
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
. Основное отличие состоит в том, что вы используете 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
и передайте значение 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?>
или класс данных для захвата начального и конечного значений.
См. также
,Средства выбора дат позволяют пользователям выбирать дату, диапазон дат или и то, и другое. Они используют диалоговое окно календаря или ввод текста, чтобы пользователи могли выбирать даты.
Типы
Существует три типа выбора даты:
- Закреплено : отображается внутри макета. Он подходит для компактных макетов, где выделенный диалог может показаться навязчивым.
- Модальное окно : отображается в виде диалогового окна, накладывающего содержимое приложения. Это обеспечивает четкую фокусировку на выборе даты.
- Модальный ввод : объединяет текстовое поле с модальным выбором даты.
Вы можете реализовать эти средства выбора дат в своем приложении, используя следующие составные элементы:
-
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
.- Кнопка со значком служит аргументом для параметра
trailingIcon
OutlinedTextField
. - Переменная состояния
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
. Основное отличие состоит в том, что вы используете 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
и передайте значение 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?>
или класс данных для захвата начального и конечного значений.