===== 목적 =====
안드로이드 Jetpack compose로 날짜 선택도구(Date Picker)를 구현해 보자
===== 기본 컴퍼넌트 =====
==== 1. Date Picker ====
안드로이드에서는 DatePicker에서 선택 한 일자를 Long형태로, DatePickerState로 반환해 준다.
따라서 rememberDatePickerState()로 지정된 변수를 반환해 주면 날짜를 Long 형태롤 얻을 수 있다.
참고로, DatePicker는 Dialog 형태의 팝업으로 나와야 할 것이다. 이를 코드로 하면 다음과 같다.
// 캘린더
@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(stringResource(id = R.string.confirm))
}
},
dismissButton = {
TextButton(onClick = onDismiss) {
Text(stringResource(id = R.string.dismiss))
}
}
) {
DatePicker(state = datePickerState,
title = {
Text(text = " 날짜 선택")
},
headline = {
Text(text = " 직접 날자를 입력하려며 펜 버튼 클릭")
},
)
}
}
==== 2. Long값을 String으로 변환하는 컨버터 ====
날짜를 Long값으로 가져오므로, 이를 사람이 읽을 수 있게 String으로 반환해야 한다.
SimpleDateFormat이란 함수를 이용하면 날자의 Format을 정할 수 있다.
// 날자의 Long값을 String으로 변환하는 함수
fun convertMillisToDate(millis: Long?): String {
var message : String = ""
if (millis != null) {
val date = Date(millis)
message = SimpleDateFormat("yyyy-MM-dd", Locale.KOREAN).format(date)
}else {
message = "날짜가 선택되지 않았습니다."
}
return message
}
===== 선택한 날짜를 텍스트필드와 연결하기 =====
날짜선택도구를 만들었으면, 이를 텍스트 필드와 연결해야 할 것이다. 라벨로 보여줄 수도 있지만 관례적으로 텍스트 필드를 통해 날짜를 보여주므로 우리도 텍스트 필드로 날자를 보여주게 만들어보자.
// 날짜 입력 컴퍼저블
@Composable
fun dateAddWithCalendar(storedDate : Long?) : Long
{
var showDatePicker by remember { mutableStateOf(false) }
var selectedDate by remember { mutableStateOf(storedDate) }
OutlinedTextField(
value = convertMillisToDate(selectedDate),
onValueChange = { },
label = { Text(text = stringResource(id = R.string.selectDate), color = Color.Blue, fontSize = 14.sp, style = TextStyle(fontFamily = fontGoryeong)) },
readOnly = true,
trailingIcon = {
IconButton(onClick = { showDatePicker = !showDatePicker }) {
Icon(
imageVector = Icons.Default.DateRange,
contentDescription = "Select date"
)
}
},
textStyle = TextStyle(fontFamily = fontkjcMyungjo, fontSize = 16.sp, fontWeight = FontWeight.SemiBold, fontStyle = FontStyle.Normal),
keyboardOptions = KeyboardOptions.Default,
modifier = Modifier
.fillMaxWidth()
.height(64.dp)
)
if (showDatePicker)
{
DatePickerModal(onDateSelected = { selectedDate = it}, onDismiss = {showDatePicker = false })
}
return selectedDate?:12133
}
===== 실제 코드에서 구현하기 =====
다음은 Json으로 받아온 날자를 다시 Long값으로 변환한 후에 이를 날자 선택 텍스트 필드에 변수로 넣어주고,
날찌입력 선택도구에서 날자를 선택하면 텍스트 필드의 값이 다시 바뀌는 것을 구현한 것이다.
val jsonAttackedDate = jsonElementObject.optString("attackedDate", Date.from(Instant.now()).time.toString())
val attackedDate by remember { mutableStateOf(jsonAttackedDate.toLongOrNull())}
var setAttackedDate : Long? = 1
Spacer(modifier = Modifier.height(40.dp))
ElevatedCard(elevation = CardDefaults.cardElevation(defaultElevation = 6.dp), modifier = Modifier
.fillMaxWidth()
.padding(6.dp)) {
Column(
modifier = Modifier
.fillMaxWidth()
.padding(8.dp), horizontalAlignment = Alignment.Start
) {
setAttackedDate = dateAddWithCalendar(attackedDate)
}
}