Compose에서 DatePicker 및 TimePicker: Material3 날짜/시간 선택

발행: (2026년 3월 2일 오전 10:19 GMT+9)
3 분 소요
원문: Dev.to

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

다음은 DatePickerDialogOutlinedTextField를 결합한 재사용 가능한 컴포저블 예시입니다:

@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를 구현할 수 있습니다.

8 Android App Templates → https://myougatheax.gumroad.com/

0 조회
Back to Blog

관련 글

더 보기 »