===== 개요 =====
다음과 같은 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)
}
}