Compose DatePickerDialog - 날짜 선택 제한

DatePickerDialog

DatePickerDialog = DatePicker + Dialog 즉, 날짜를 선택할 수 있는 DatePicker를 Dialog 형태로 나타내는 컴포넌트이다.

그림1. DatePicker

사용자에게 특정 날짜를 입력 받기 위해서 사용자가 간단히 선택할 수 있는 UI를 제공하며

Dialog 형태로 나타나므로 공간을 낭비하지 않아서 날짜를 입력 받고자 할 때 유용하게 사용할 수 있다.



DatePickerDialog 구현

DatePickerDialog 부분을 살펴보기 전에 우선 UI 부분을 살펴보면

  • date : 선택한 날짜
  • showDatePicker : DatePickerDialog 보이기/숨기기 여부 판별

그림2. 버튼 클릭 시 Dialog Open

var date by remember { mutableStateOf("Open date picker dialog") }
var showDatePicker by remember { mutableStateOf(false) }
if (showDatePicker) {
MyDatePickerDialog(
onDateSelected = { date = it },
onDismiss = { showDatePicker = false }
)
}

Box(modifier = Modifier.padding(innerPadding).fillMaxSize(),
contentAlignment = Alignment.Center) {
Button(onClick = { showDatePicker = true }) {
Text(text = date)
}
}

버튼을 클릭하면 showDatePicker 변수를 true로 초기화하고

그에 따라서 정의한 MyDatePickerDialog 컴포저블 함수를 통해 DatePickerDialog가 나타나게 된다.



MyDatePickerDialog

다음으로 정의한 MyDatePickerDialog 컴포저블 함수를 살펴보면

  • datePickerState : DatePicker의 상태값
  • selectedDate : 선택한 날짜를 문자열 형태로 갖는 변수

여기서 datePickerState 변수를 보면 isSelectableDate 함수를 override 하고 있다.

이는 DatePicker에서 선택이 가능한 날짜를 제한할 수 있는데

System.currentTimeMillis() = 현재 시간보다 큰 값이기 때문에 즉, 오늘 이후에 날짜만(=미래) 선택 가능하도록 제한할 수 있다.

물론 return utcTimeMillis <= System.currentTimeMillis() 같이 반대일 경우에는 오늘 이전에(=과거) 날짜만 선택이 가능해진다.

💡 이런 식으로 만약 앞으로 일정에 대한 날짜를 입력 받고 하는 경우면, 과거가 아닌 미래에 대한 날짜일 것이므로 선택 가능한 날짜를 제한할 수 있다.


@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun MyDatePickerDialog(
onDateSelected: (String) -> Unit,
onDismiss: () -> Unit
) {
val datePickerState = rememberDatePickerState(selectableDates = object : SelectableDates {
override fun isSelectableDate(utcTimeMillis: Long): Boolean {
return utcTimeMillis >= System.currentTimeMillis()
}
})

val selectedDate = datePickerState.selectedDateMillis?.let {
convertMillisToDate(it)
} ?: ""
    ...<DatePicker>...
}

private fun convertMillisToDate(millis: Long): String {
val formatter = SimpleDateFormat("yyyy-MM-dd")
return formatter.format(Date(millis))
}

convertMillisToDate 함수는 SimpleDateFormat을 사용하여 Long 형태의 시간을 yyyy-MM-dd(년-월-일) 형태로 변환하는 함수이다.


그림3. 실행 화면


마지막으로 DatePickerDialog 부분을 보면

  • onDismissRequest : Dialog가 닫혔을 경우 동작
  • confirmButton : 확인 버튼
  • dismissButton : 취소 버튼

DatePicker 상태 값으로 앞서 선언한 datePickerState 변수를 전달해 주면 된다.

DatePickerDialog(
onDismissRequest = { onDismiss() },
confirmButton = {
Button(onClick = {
onDateSelected(selectedDate)
onDismiss()
}

) {
Text(text = "OK")
}
},
dismissButton = {
Button(onClick = {
onDismiss()
}) {
Text(text = "Cancel")
}
}
) {
DatePicker(
state = datePickerState
)
}



참고

전체 코드 | Github



댓글

이 블로그의 인기 게시물

Compose 스크롤 시 AppBar 처리 - TopAppBarScrollBehavior

Compose status bar transparent - 상태 바 색 변경

Compose Toast message - 토스트 메시지 사용