Pemilih tanggal memungkinkan pengguna memilih tanggal, rentang tanggal, atau keduanya. Dialog ini menggunakan dialog kalender atau input teks untuk memungkinkan pengguna memilih tanggal.
Jenis
Ada tiga jenis pemilih tanggal:
- Terpasang ke dok: Muncul inline dalam tata letak. Cocok untuk tata letak yang ringkas, yang mungkin akan terganggu jika menggunakan dialog khusus.
- Modal: Muncul sebagai dialog yang menutupi konten aplikasi. Hal ini memberikan fokus yang jelas pada pemilihan tanggal.
- Input modal: Menggabungkan kolom teks dengan pemilih tanggal modal.
Anda dapat menerapkan pemilih tanggal ini di aplikasi menggunakan composable berikut:
DatePicker: Composable umum untuk pemilih tanggal. Penampung yang Anda gunakan menentukan apakah penampung tersebut ditambatkan atau model.DatePickerDialog: Penampung untuk pemilih tanggal input modal dan modal.DateRangePicker: Untuk pemilih tanggal apa pun yang memungkinkan pengguna memilih rentang dengan tanggal mulai dan akhir.
Negara Bagian
Parameter utama yang dimiliki oleh berbagai composable pemilih tanggal adalah
state, yang menggunakan objek DatePickerState atau
DateRangePickerState. Propertinya menangkap informasi tentang
pilihan pengguna menggunakan pemilih tanggal, seperti tanggal yang dipilih saat ini.
Untuk mengetahui informasi selengkapnya tentang cara menggunakan tanggal yang dipilih, lihat bagian Menggunakan tanggal yang dipilih.
Pemilih tanggal yang ditambatkan
Dalam contoh berikut, ada kolom teks yang meminta pengguna untuk memasukkan tanggal lahir mereka. Saat pengguna mengklik ikon kalender di kolom, pemilih tanggal yang terpasang akan terbuka di bawah kolom input.
@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)) }
Poin penting tentang kode
- Pemilih tanggal akan muncul saat pengguna mengklik
IconButton.- Tombol ikon berfungsi sebagai argumen untuk parameter
trailingIconOutlinedTextField. - Variabel status
showDatePickermengontrol visibilitas pemilih tanggal yang diletakkan di panel.
- Tombol ikon berfungsi sebagai argumen untuk parameter
- Penampung pemilih tanggal adalah composable
Popup, yang menempatkan konten di atas tanpa memengaruhi tata letak elemen lain. selectedDatemengambil nilai tanggal yang dipilih dari objekDatePickerStatedan memformatnya menggunakan fungsiconvertMillisToDate.- Tanggal yang dipilih akan muncul di kolom teks.
- Pemilih tanggal yang ditambatkan diposisikan di bawah kolom teks menggunakan pengubah
offset. Boxdigunakan sebagai penampung root untuk memungkinkan pelapisan kolom teks dan pemilih tanggal yang tepat.
Hasil
Setelah mengklik ikon kalender, implementasi ini akan muncul sebagai berikut:
Pemilih tanggal modal
Pemilih tanggal modal menampilkan dialog yang mengambang di atas layar. Untuk mengimplementasikannya, buat DatePickerDialog dan teruskan 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) } }
Poin penting tentang kode
- Fungsi composable
DatePickerModalmenampilkan pemilih tanggal modal. - Ekspresi lambda
onDateSelecteddijalankan saat pengguna memilih tanggal.- Fungsi ini mengekspos tanggal yang dipilih ke composable induk.
- Ekspresi lambda
onDismissdijalankan saat pengguna menutup dialog.
Hasil
Implementasi ini akan terlihat seperti berikut:
Pemilih tanggal modal input
Pemilih tanggal modal dengan input menampilkan dialog yang mengambang di atas layar dan memungkinkan pengguna memasukkan tanggal.
@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) } }
Poin penting tentang kode
Hal ini sangat mirip dengan contoh pemilih tanggal modal. Perbedaan utamanya adalah sebagai berikut:
- Parameter
initialDisplayModemenetapkan mode tampilan awal keDisplayMode.Input.
Pemilih tanggal dengan rentang
Anda dapat membuat pemilih tanggal yang memungkinkan pengguna memilih rentang antara tanggal mulai
dan tanggal akhir. Untuk melakukannya, gunakan DateRangePicker.
Penggunaan DateRangePicker pada dasarnya sama dengan DatePicker. Anda dapat
menggunakannya untuk pemilih yang diletakkan sebagai turunan dari PopUp, atau Anda dapat menggunakannya sebagai
pemilih modal dan meneruskannya ke DatePickerDialog. Perbedaan utamanya adalah
Anda menggunakan DateRangePickerState, bukan DatePickerState.
Cuplikan berikut menunjukkan cara membuat pemilih tanggal modal dengan rentang:
@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) ) } }
Poin penting tentang kode
- Parameter
onDateRangeSelectedadalah callback yang menerimaPair<Long?, Long?>yang mewakili tanggal mulai dan akhir yang dipilih. Tindakan ini memberi composable induk akses ke rentang yang dipilih. rememberDateRangePickerState()membuat status untuk pemilih rentang tanggal.DatePickerDialogmembuat penampung dialog modal.- Di pengendali
onClicktombol konfirmasi,onDateRangeSelectedmeneruskan rentang yang dipilih ke composable induk. - Composable
DateRangePickerberfungsi sebagai konten dialog.
Hasil
Implementasi ini akan terlihat seperti berikut:
Gunakan tanggal yang dipilih
Untuk mengambil tanggal yang dipilih, lacak tanggal tersebut di composable induk sebagai Long dan
teruskan nilai ke DatePicker di onDateSelected. Cuplikan berikut
menunjukkan hal ini, meskipun Anda dapat melihat implementasi lengkapnya di aplikasi cuplikan
resmi.
// ... 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 } ) } // ...
Pada dasarnya, hal yang sama berlaku untuk pemilih tanggal rentang, meskipun Anda perlu
menggunakan Pair<Long?, Long?> atau class data untuk mengambil nilai awal dan akhir.