เครื่องมือเลือกวันที่ช่วยให้ผู้ใช้เลือกวันที่ ช่วงวันที่ หรือทั้งสองอย่างได้ โดยใช้กล่องโต้ตอบปฏิทินหรือการป้อนข้อความเพื่อให้ผู้ใช้เลือกวันที่
ประเภท
เครื่องมือเลือกวันที่มี 3 ประเภท ได้แก่
- อยู่บนแท่นชาร์จ: ปรากฏในบรรทัดภายในเลย์เอาต์ เหมาะสำหรับเลย์เอาต์ขนาดกะทัดรัดที่กล่องโต้ตอบเฉพาะอาจดูรบกวน
- โมดัล: ปรากฏเป็นกล่องโต้ตอบที่ซ้อนทับเนื้อหาของแอป ซึ่งช่วยให้ผู้ใช้มุ่งความสนใจไปที่การเลือกวันที่ได้อย่างชัดเจน
- การป้อนข้อมูลแบบโมดัล: รวมช่องข้อความกับเครื่องมือเลือกวันที่แบบโมดัล
คุณสามารถใช้ฟังก์ชันที่ประกอบกันได้ต่อไปนี้เพื่อใช้เครื่องมือเลือกวันที่เหล่านี้ในแอป
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- ปุ่มไอคอนทำหน้าที่เป็นอาร์กิวเมนต์สำหรับพารามิเตอร์
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?> หรือคลาสข้อมูลเพื่อเก็บค่าเริ่มต้นและค่าสิ้นสุด