Os seletores de data permitem que os usuários selecionem uma data, um período ou ambos. Eles usam uma caixa de diálogo de calendário ou uma entrada de texto para permitir que os usuários selecionem datas.
Tipos
Há três tipos de seletor de data:
- Na base: aparece inline no layout. É adequado para layouts compactos em que uma caixa de diálogo dedicada pode parecer intrusiva.
- Modal: aparece como uma caixa de diálogo sobreposta ao conteúdo do app. Isso fornece um foco claro na seleção de datas.
- Entrada modal: combina um campo de texto com um seletor de data modal.
Implemente esses seletores de data no seu app usando o seguinte que podem ser compostos:
DatePicker
: elemento combinável geral para um seletor de data. O contêiner que você usa determina se ele está ancorado ou em modelo.DatePickerDialog
: o contêiner para os seletores de data de entrada modal e modal.DateRangePicker
: para qualquer seletor de data em que o usuário possa selecionar um intervalo com datas de início e término.
Estado
O principal parâmetro que os diferentes elementos combináveis do seletor de data têm em comum é
state
, que usa um DatePickerState
ou
DateRangePickerState
. As propriedades deles capturam informações sobre
da seleção do usuário usando o seletor de data, como a data selecionada no momento.
Para mais informações sobre como você pode usar a data selecionada, consulte a seção Usar seção de data selecionada.
Seletor de datas fixado
No exemplo a seguir, há um campo de texto que solicita que o usuário insira a data de nascimento. Quando o usuário clica no ícone de calendário no campo, um seletor de datas fixado é aberto abaixo do campo de entrada.
@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)) }
Pontos principais sobre o código
- O seletor de data aparece quando o usuário clica em
IconButton
.- O botão de ícone serve como argumento para o parâmetro
trailingIcon
doOutlinedTextField
. - A variável de estado
showDatePicker
controla a visibilidade do seletor de data acoplado.
- O botão de ícone serve como argumento para o parâmetro
- O contêiner do seletor de data é um elemento combinável
Popup
, que se sobrepõe à do conteúdo sem afetar o layout de outros elementos. selectedDate
captura o valor da data selecionada doDatePickerState
e o formata usando oconvertMillisToDate
função.- A data selecionada aparece no campo de texto.
- O seletor de data na base é posicionado abaixo do campo de texto usando um
offset
. - Um
Box
é usado como o contêiner raiz para permitir a estratificação adequada do campo de texto e do seletor de data.
Resultados
Depois de clicar no ícone do calendário, essa implementação aparece da seguinte maneira:

Seletor de data modal
Um seletor de data modal mostra uma caixa de diálogo que flutua sobre a tela. Para implementar
crie um DatePickerDialog
e transmita a ele um 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) } }
Pontos principais sobre o código
- A função combinável
DatePickerModal
mostra um seletor de data modal. - A expressão lambda
onDateSelected
é executada quando o usuário seleciona uma data.- Ele expõe a data selecionada ao elemento combinável pai.
- A expressão lambda
onDismiss
é executada quando o usuário dispensa o caixa de diálogo.
Resultados
Essa implementação aparece da seguinte maneira:

Input modal date picker
Um seletor de data modal com entrada mostra uma caixa de diálogo que flutua sobre a tela e permite que o usuário insira uma data.
@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) } }
Pontos principais sobre o código
Isso é muito parecido com o exemplo de seletor de data modal. O principal a diferença é a seguinte:
- O parâmetro
initialDisplayMode
define o modo de exibição inicial comoDisplayMode.Input
.

Seletor de datas com período
Você pode criar um seletor de datas que permita ao usuário selecionar um período entre uma data
de início e uma de término. Para fazer isso, use DateRangePicker
.
O uso de DateRangePicker
é essencialmente o mesmo que DatePicker
. Você pode
usá-lo para um seletor fixado como filho de PopUp
ou como um
seletor modal e transmiti-lo para DatePickerDialog
. A principal diferença é
que você usa DateRangePickerState
em vez de DatePickerState
.
O snippet a seguir demonstra como criar um seletor de data modal com uma intervalo:
@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) ) } }
Pontos principais sobre o código
- O parâmetro
onDateRangeSelected
é um callback que recebe umPair<Long?, Long?>
que representa as datas de início e término selecionadas. Isso concede ao elemento combinável pai acesso ao intervalo selecionado. rememberDateRangePickerState()
cria o estado para o seletor de período de datas.- O
DatePickerDialog
cria um contêiner de caixa de diálogo modal. - No gerenciador
onClick
do botão de confirmação,onDateRangeSelected
transmite o intervalo selecionado ao elemento combinável pai. - O elemento combinável
DateRangePicker
serve como o conteúdo da caixa de diálogo.
Resultados
Essa implementação aparece da seguinte maneira:

Usar a data selecionada
Para capturar a data selecionada, rastreie-a no elemento combinável pai como um Long
.
Transmita o valor para a DatePicker
em onDateSelected
. O snippet abaixo
demonstra isso, embora você possa conferir a implementação completa no app oficial
de snippets.
// ... 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 } ) } // ...
O mesmo se aplica aos seletores de datas de intervalo, mas é necessário
usar uma Pair<Long?, Long?>
ou uma classe de dados para capturar os valores de início e término.