안드로이드 Jetpack compose로 날짜 선택도구(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 = " 직접 날자를 입력하려며 펜 버튼 클릭") }, ) } }
날짜를 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<Long?>(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) } }