사용자가 날짜 선택을 편하게 할 수 있도록 DatePicker와 OutlinedTextField를 조합하여 날짜 선택 기능을 제공하는 DatePickerField 컴포저블을 구현하기로 했다.
주요 기능으로는 다음 세 가지 기능이 있다.
DatePickerField는 사용자가 날짜를 선택하고 텍스트 필드에 표시되도록 구성
💡 주요 구현 포인트
- OutlinedTextField: 날짜를 텍스트 형식으로 표시
- IconButton: 텍스트 필드의 우측에 달력 아이콘 제공
- 모달 연결: showModal 상태에 따라 DatePickerModal을 표시
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun DatePickerField(
label: String,
selectedDate: Long?,
onDateSelected: (Long?) -> Unit
) {
var showModal by remember { mutableStateOf(false) }
val formattedDate = selectedDate?.let { convertMillisToDate(it) } ?: ""
Column(
modifier = Modifier.fillMaxWidth()
) {
// 텍스트 라벨
Text(
text = label,
color = MaterialTheme.colorScheme.secondary,
fontSize = 16.sp,
modifier = Modifier.padding(bottom = 10.dp)
)
// 날짜를 표시하는 OutlinedTextField
OutlinedTextField(
value = formattedDate,
onValueChange = { },
placeholder = {
Text(
text = "언제까지 끝낼까요?",
color = MaterialTheme.colorScheme.onSecondary,
fontSize = 13.sp
)
},
readOnly = true,
trailingIcon = {
IconButton(onClick = { showModal = true }) {
Icon(
painter = painterResource(id = R.drawable.ic_schedule),
contentDescription = "Select date",
tint = MaterialTheme.colorScheme.onSecondary
)
}
},
modifier = Modifier
.fillMaxWidth()
.wrapContentHeight(),
shape = RoundedCornerShape(10.dp),
colors = TextFieldDefaults.outlinedTextFieldColors(
focusedBorderColor = Color(0xFFDFEAF2),
unfocusedBorderColor = Color(0xFFDFEAF2),
cursorColor = MaterialTheme.colorScheme.primary
)
)
// 날짜 선택 모달 표시
if (showModal) {
DatePickerModal(
onDateSelected = { date ->
onDateSelected(date)
showModal = false
},
onDismiss = { showModal = false }
)
}
}
}
DatePickerModal은 Compose의 DatePickerDialog를 활용하여 날짜를 선택할 수 있는 모달을 제공
💡 주요 구현 포인트
- DatePickerDialog: 모달 대화상자를 통해 날짜 선택 UI 제공.
- DatePicker: state를 사용하여 선택된 날짜를 추적.
- 버튼 구성: "확인" 및 "취소" 버튼으로 모달을 종료.
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun DatePickerModal(
onDateSelected: (Long?) -> Unit,
onDismiss: () -> Unit
) {
val datePickerState = rememberDatePickerState()
DatePickerDialog(
onDismissRequest = onDismiss,
confirmButton = {
TextButton(onClick = {
onDateSelected(datePickerState.selectedDateMillis)
onDismiss()
}) {
Text("확인")
}
},
dismissButton = {
TextButton(onClick = onDismiss) {
Text("취소")
}
}
) {
DatePicker(state = datePickerState)
}
}
fun convertMillisToDate(millis: Long): String {
val formatter = SimpleDateFormat("yyyy/MM/dd", Locale.getDefault())
return formatter.format(Date(millis))
}