===== 개요 ===== 다음과 같은 Time Dial을 구현하려고 한다. {{:android:timedialpicker.png?600|Time Dial Picker}} ===== TimePicker 및 이를 포함한 다이알로그 만들기 ===== timePicker는 TimePickerState를 이용하여 변수를 넘긴다. 시간과 분을 셋팅하는 것은 다음과 같다. val timePickerState = rememberTimePickerState( initialHour = currentTime.get(Calendar.HOUR_OF_DAY), initialMinute = currentTime.get(Calendar.MINUTE), is24Hour = false, ) 따라서 TimePicker는 다음과 같이 만들 수 있다. ==== 1. TimePicker ==== // 다이얼 시간 선택 도구 @OptIn(ExperimentalMaterial3Api::class) // [START android_compose_components_timepickerdialog] @Composable fun DialWithDialog( onConfirm: (TimePickerState) -> Unit, onDismiss: () -> Unit, ) { val currentTime = Calendar.getInstance() val timePickerState = rememberTimePickerState( initialHour = currentTime.get(Calendar.HOUR_OF_DAY), initialMinute = currentTime.get(Calendar.MINUTE), is24Hour = false, ) TimePickerDialog( onDismiss = { onDismiss() }, onConfirm = { onConfirm(timePickerState) } ) { TimePicker( state = timePickerState, ) } } ==== 2. 다이알로그 ==== 타임피커를 다이알로그 형태로 만들 것이므로 다이알로그로 싸주었다. // 타임피커 다이알로그 @Composable fun TimePickerDialog( onDismiss: () -> Unit, onConfirm: () -> Unit, content: @Composable () -> Unit ) { AlertDialog( onDismissRequest = onDismiss, dismissButton = { TextButton(onClick = { onDismiss() }) { Text(stringResource(id = R.string.dismiss)) } }, confirmButton = { TextButton(onClick = { onConfirm() }) { Text(stringResource(id = R.string.confirm)) } }, text = { content() } ) } // [END android_compose_components_timepickerdialog] ===== 독립된 컴퍼저블로 만들기 ===== 위에서 만들 TimePicker를 텍스틀필드와 연동하는 방법이다. 참고로, timepickerstate로 받아온 정확한 시간뿐만 아니라, "00시경"과 같이 텍스트도 같이 입력받기 위하여 아래와 같이 코드를 짰다. // 시간 입력 컴퍼저블 @OptIn(ExperimentalMaterial3Api::class) @Composable fun timeAddWithDial(incidentTime : String) : String { var showTimeDial by remember { mutableStateOf(false) } var selectedTime: TimePickerState? by remember { mutableStateOf(null) } var timeText : String by remember { mutableStateOf(convertInitialToTimeString(incidentTime)) } Column(modifier = Modifier.fillMaxWidth(), verticalArrangement = Arrangement.spacedBy(8.dp)) { OutlinedTextField( value = timeText, onValueChange = { timeText = it}, label = { Text(text = stringResource(id = R.string.selectTime), color = Color.Blue, fontSize = 14.sp, style = TextStyle(fontFamily = fontGoryeong)) }, readOnly = false, trailingIcon = { IconButton(onClick = { showTimeDial = !showTimeDial }) { Icon( imageVector = Icons.Default.Face, contentDescription = "Select Time of day" ) } }, textStyle = TextStyle(fontFamily = fontkjcMyungjo, fontSize = 16.sp, fontWeight = FontWeight.SemiBold, fontStyle = FontStyle.Normal), keyboardOptions = KeyboardOptions.Default, modifier = Modifier .fillMaxWidth() .height(64.dp) ) Text(text = "* 대충 적어도 됩니다(예 : 정오경, 저녁시간, 새벽녘)", style = MaterialTheme.typography.titleMedium) } if (showTimeDial) // 시각 선택 다이얼 { DialWithDialog(onConfirm = { selectedTime = it; showTimeDial = false; timeText = convertTimeToString(selectedTime) }, onDismiss = { showTimeDial = false } ) } return timeText } fun convertInitialToTimeString(inputText : String) : String { if (inputText == "") { return "시간이 정해지지 않았습니다" }else { return inputText } } @OptIn(ExperimentalMaterial3Api::class) fun convertTimeToString(time : TimePickerState?) : String { val cal = Calendar.getInstance() if (time != null) { // 정한 시각으로 cal.set(Calendar.HOUR_OF_DAY, time.hour) cal.set(Calendar.MINUTE, time.minute) cal.isLenient = false val calTime = SimpleDateFormat("hh:mm a", Locale.getDefault()).format(cal.time) return calTime }else { // 현재 시각으로 val calTime = SimpleDateFormat("hh:mm a", Locale.getDefault()).format(cal.time) return calTime } } 이를 실제 쓰는건 다음과 같다. [[android:datepicker|DatePicker와]] 같이 사용했다. CardTitleText("(3) 피해를 당한 날짜", "https://lawwiki.kr/doku.php/%EC%86%8C%EC%86%A1%EC%8B%A4%EB%AC%B4:%ED%98%95%EC%82%AC:%ED%8F%AD%ED%96%89") Spacer(modifier = Modifier.height(20.dp)) ElevatedCard(elevation = CardDefaults.cardElevation(defaultElevation = 6.dp), modifier = Modifier .fillMaxWidth() .padding(6.dp)) { Column( modifier = Modifier .fillMaxWidth() .padding(8.dp), horizontalAlignment = Alignment.Start, verticalArrangement = Arrangement.spacedBy(20.dp) ) { sueItem.dateOfIncident = dateAddWithCalendar(sueItem.dateOfIncident) sueItem.timeOfIncident = timeAddWithDial(sueItem.timeOfIncident) } }