Compose에서 DatePicker 및 TimePicker: Material3 날짜/시간 선택
Source: Dev.to
DatePickerDialog & State Management
DatePickerDialog 컴포저블에 rememberDatePickerState() 를 함께 사용하면 날짜 선택을 제어된 방식으로 처리할 수 있습니다:
var showDatePicker by remember { mutableStateOf(false) }
val datePickerState = rememberDatePickerState()
if (showDatePicker) {
DatePickerDialog(
onDismissRequest = { showDatePicker = false },
confirmButton = {
TextButton(onClick = {
val selectedDate = datePickerState.selectedDateMillis
showDatePicker = false
}) {
Text("OK")
}
}
) {
DatePicker(state = datePickerState)
}
}
Button(onClick = { showDatePicker = true }) {
Text("Select Date")
}
SelectableDates for Range Restriction
SelectableDates 인터페이스를 사용해 선택 가능한 날짜 범위를 제한할 수 있습니다:
class DateRangeValidator(
private val minDateMillis: Long,
private val maxDateMillis: Long
) : SelectableDates {
override fun isSelectableDate(utcTimeMillis: Long): Boolean {
return utcTimeMillis >= minDateMillis && utcTimeMillis = 2024 && year Unit,
}
}
Example: Custom DatePickerField
다음은 DatePickerDialog와 OutlinedTextField를 결합한 재사용 가능한 컴포저블 예시입니다:
@Composable
fun DatePickerField(
value: LocalDateTime,
onValueChange: (LocalDateTime) -> Unit,
label: String,
modifier: Modifier = Modifier
) {
var showPicker by remember { mutableStateOf(false) }
val datePickerState = rememberDatePickerState(
initialSelectedDateMillis = value.toMillis()
)
OutlinedTextField(
value = value.format(DateTimeFormatter.ofPattern("MMM dd, yyyy")),
onValueChange = {},
label = { Text(label) },
readOnly = true,
trailingIcon = {
IconButton(onClick = { showPicker = true }) {
Icon(Icons.Default.DateRange, contentDescription = null)
}
},
modifier = modifier
)
if (showPicker) {
DatePickerDialog(
onDismissRequest = { showPicker = false },
confirmButton = {
TextButton(onClick = {
datePickerState.selectedDateMillis?.let { mills ->
onValueChange(
LocalDateTime.ofInstant(
Instant.ofEpochMilli(mills),
ZoneId.systemDefault()
)
)
}
showPicker = false
}) {
Text("OK")
}
}
) {
DatePicker(state = datePickerState)
}
}
}
Best Practices
- State Management:
rememberDatePickerState()를 사용해 재구성 시에도 상태를 유지하세요. - Validation: 비즈니스 로직 제약을 적용하려면
SelectableDates를 구현합니다. - User Feedback: 선택된 날짜/시간을 UI에 즉시 표시해 주세요.
- Accessibility: 피커 필드에 적절한 라벨과 콘텐츠 설명을 제공하여 접근성을 확보합니다.
- Timezone Awareness: 타임스탬프를 변환할 때 타임존 처리를 명시적으로 수행하세요.
Material3 날짜/시간 피커는 현대적인 Material Design 규격을 따르는 사용자 경험을 제공하므로, 사용자들이 기대하는 UI를 구현할 수 있습니다.