시간 선택 도구 대화상자

시간 선택 도구는 대화상자에 자주 표시됩니다. 대화상자의 비교적 일반적이고 최소한의 구현을 사용하거나 더 유연하게 맞춤 대화상자를 구현할 수 있습니다.

시간 선택기 상태를 사용하는 방법을 비롯한 일반적인 대화상자에 관한 자세한 내용은 시간 선택기 가이드를 참고하세요.

기본 예

시간 선택 도구의 대화상자를 만드는 가장 간단한 방법은 AlertDialog를 구현하는 컴포저블을 만드는 것입니다. 다음 스니펫은 이 접근 방식을 사용하는 상대적으로 최소한의 대화상자의 예를 보여줍니다.

@Composable
fun DialWithDialogExample(
    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 = true,
    )

    TimePickerDialog(
        onDismiss = { onDismiss() },
        onConfirm = { onConfirm(timePickerState) }
    ) {
        TimePicker(
            state = timePickerState,
        )
    }
}

@Composable
fun TimePickerDialog(
    onDismiss: () -> Unit,
    onConfirm: () -> Unit,
    content: @Composable () -> Unit
) {
    AlertDialog(
        onDismissRequest = onDismiss,
        dismissButton = {
            TextButton(onClick = { onDismiss() }) {
                Text("Dismiss")
            }
        },
        confirmButton = {
            TextButton(onClick = { onConfirm() }) {
                Text("OK")
            }
        },
        text = { content() }
    )
}

이 스니펫의 핵심 사항은 다음과 같습니다.

  1. DialWithDialogExample 컴포저블은 대화상자에 TimePicker를 래핑합니다.
  2. TimePickerDialog는 다음 매개변수를 사용하여 AlertDialog를 만드는 맞춤 컴포저블입니다.
    • onDismiss: 사용자가 닫기 버튼이나 뒤로 탐색을 통해 대화상자를 닫을 때 호출되는 함수입니다.
    • onConfirm: 사용자가 '확인' 버튼을 클릭할 때 호출되는 함수입니다.
    • content: 대화상자 내에 시간 선택기를 표시하는 컴포저블입니다.
  3. AlertDialog에는 다음이 포함됩니다.
    • '닫기'라는 라벨이 지정된 닫기 버튼
    • '확인' 라벨이 지정된 확인 버튼
    • text 매개변수로 전달된 시간 선택 도구 콘텐츠입니다.
  4. DialWithDialogExample는 현재 시간으로 TimePickerState를 초기화하고 TimePicker 함수와 onConfirm 함수 모두에 전달합니다.
제목, 모드 전환, 닫기 및 확인 버튼을 구현하는 AlertDialog의 시간 선택 도구입니다.
그림 1. AlertDialog의 시간 선택기

고급 예

이 스니펫은 Jetpack Compose에서 맞춤설정 가능한 시간 선택기 대화상자의 고급 구현을 보여줍니다.

@Composable
fun AdvancedTimePickerExample(
    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 = true,
    )

    /** Determines whether the time picker is dial or input */
    var showDial by remember { mutableStateOf(true) }

    /** The icon used for the icon button that switches from dial to input */
    val toggleIcon = if (showDial) {
        Icons.Filled.EditCalendar
    } else {
        Icons.Filled.AccessTime
    }

    AdvancedTimePickerDialog(
        onDismiss = { onDismiss() },
        onConfirm = { onConfirm(timePickerState) },
        toggle = {
            IconButton(onClick = { showDial = !showDial }) {
                Icon(
                    imageVector = toggleIcon,
                    contentDescription = "Time picker type toggle",
                )
            }
        },
    ) {
        if (showDial) {
            TimePicker(
                state = timePickerState,
            )
        } else {
            TimeInput(
                state = timePickerState,
            )
        }
    }
}

@Composable
fun AdvancedTimePickerDialog(
    title: String = "Select Time",
    onDismiss: () -> Unit,
    onConfirm: () -> Unit,
    toggle: @Composable () -> Unit = {},
    content: @Composable () -> Unit,
) {
    Dialog(
        onDismissRequest = onDismiss,
        properties = DialogProperties(usePlatformDefaultWidth = false),
    ) {
        Surface(
            shape = MaterialTheme.shapes.extraLarge,
            tonalElevation = 6.dp,
            modifier =
            Modifier
                .width(IntrinsicSize.Min)
                .height(IntrinsicSize.Min)
                .background(
                    shape = MaterialTheme.shapes.extraLarge,
                    color = MaterialTheme.colorScheme.surface
                ),
        ) {
            Column(
                modifier = Modifier.padding(24.dp),
                horizontalAlignment = Alignment.CenterHorizontally
            ) {
                Text(
                    modifier = Modifier
                        .fillMaxWidth()
                        .padding(bottom = 20.dp),
                    text = title,
                    style = MaterialTheme.typography.labelMedium
                )
                content()
                Row(
                    modifier = Modifier
                        .height(40.dp)
                        .fillMaxWidth()
                ) {
                    toggle()
                    Spacer(modifier = Modifier.weight(1f))
                    TextButton(onClick = onDismiss) { Text("Cancel") }
                    TextButton(onClick = onConfirm) { Text("OK") }
                }
            }
        }
    }
}

이 스니펫의 핵심 사항은 다음과 같습니다.

  1. AdvancedTimePickerExample 컴포저블은 맞춤설정 가능한 시간 선택기 대화상자를 만듭니다.
  2. AlertDialog보다 유연성을 높이기 위해 Dialog 컴포저블을 사용합니다.
  3. 이 대화상자에는 맞춤설정 가능한 제목과 다이얼 모드와 입력 모드 간에 전환하는 전환 버튼이 포함되어 있습니다.
  4. Surface는 너비와 높이 모두에 IntrinsicSize.Min를 사용하여 대화상자에 도형과 고도를 적용합니다.
  5. ColumnRow 레이아웃은 대화상자의 구조 구성요소를 제공합니다.
  6. 이 예에서는 showDial를 사용하여 선택 도구 모드를 추적합니다.
    • IconButton는 모드를 전환하여 아이콘을 적절하게 업데이트합니다.
    • 대화상자 콘텐츠는 showDial 상태에 따라 TimePickerTimeInput 간에 전환됩니다.

이 고급 구현은 앱의 다양한 사용 사례에 맞게 조정할 수 있는 고도로 맞춤설정 가능하고 재사용 가능한 시간 선택기 대화상자를 제공합니다.

이 구현은 다음과 같이 표시됩니다.

제목, 모드 전환 버튼, 닫기 및 확인 버튼을 구현하는 맞춤 대화상자의 시간 선택 도구입니다.
그림 2. 맞춤 대화상자의 시간 선택 도구

추가 리소스