목차

개요

다음과 같은 Time Dial을 구현하려고 한다.

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
    }
}

이를 실제 쓰는건 다음과 같다. 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)
                    }
                }