Selectores de horarios

Los selectores de hora permiten que los usuarios seleccionen una hora. Puedes usar los elementos componibles TimePicker y TimeInput para implementar un selector de hora en tu app.

Tipos

Existen dos tipos de selectores de hora:

  • Dial: Permite que los usuarios establezcan una hora moviendo un control alrededor de un dial.
  • Entrada: Permite que los usuarios establezcan una hora con el teclado.

En la siguiente imagen, se muestra un ejemplo de un selector de hora de marcado a la izquierda y un selector de hora de entrada a la derecha:

Un dial y un selector de hora de entrada.
Figura 1: Un dial y un selector de hora de entrada

Plataforma de la API

Para implementar un selector de hora, usa el elemento componible TimePicker o TimeInput:

  • TimePicker: Implementa un selector de hora de marcado.
  • TimeInput: Implementa un selector de hora de entrada.

State

Para TimePicker y TimeInput, también debes pasar un TimePickerState. Esto te permite establecer la hora seleccionada predeterminada que aparece en el selector. También captura la hora que el usuario seleccionó con el selector.

Diálogo

Los selectores de hora aparecen en los diálogos. Los ejemplos de esta guía no usan diálogos. Para ver ejemplos que sí usan diálogos, consulta la guía Diálogos para selectores de hora.

Selector de hora de marcado

En este fragmento, se muestra cómo implementar un selector de hora de marcado básico.

@Composable
fun DialExample(
    onConfirm: () -> Unit,
    onDismiss: () -> Unit,
) {
    val currentTime = Calendar.getInstance()

    val timePickerState = rememberTimePickerState(
        initialHour = currentTime.get(Calendar.HOUR_OF_DAY),
        initialMinute = currentTime.get(Calendar.MINUTE),
        is24Hour = true,
    )

    Column {
        TimePicker(
            state = timePickerState,
        )
        Button(onClick = onDismiss) {
            Text("Dismiss picker")
        }
        Button(onClick = onConfirm) {
            Text("Confirm selection")
        }
    }
}

Ten en cuenta lo siguiente en este fragmento:

  • Calendar.getInstance() inicializa TimePickerState con la hora actual.
  • El elemento TimePicker componible muestra el selector de hora y toma timePickerState como parámetro.
  • La implementación incluye dos botones: uno para confirmar la selección y otro para descartarlo.

Esta implementación aparece de la siguiente manera:

Un selector de hora de dial. El usuario puede seleccionar una hora con el dial.
Figura 2: Un selector de hora de dial.

Ingresar selector de hora

En este fragmento, se muestra cómo implementar un selector de hora de estilo de entrada básico.

@Composable
fun InputExample(
    onConfirm: () -> Unit,
    onDismiss: () -> Unit,
) {
    val currentTime = Calendar.getInstance()

    val timePickerState = rememberTimePickerState(
        initialHour = currentTime.get(Calendar.HOUR_OF_DAY),
        initialMinute = currentTime.get(Calendar.MINUTE),
        is24Hour = true,
    )

    Column {
        TimeInput(
            state = timePickerState,
        )
        Button(onClick = onDismiss) {
            Text("Dismiss picker")
        }
        Button(onClick = onConfirm) {
            Text("Confirm selection")
        }
    }
}

Puntos clave que debes tener en cuenta en esta implementación:

  • La estructura es, en esencia, la misma que el selector de hora del dial, con la diferencia principal de que se usa TimeInput en lugar de TimePicker.
  • El parámetro is24Hour para timePickerState se establece explícitamente en true. De forma predeterminada, este valor es false.

Esta implementación aparece de la siguiente manera:

Un selector de hora de entrada. El usuario puede ingresar una hora con los campos de texto.
Figura 3: Un selector de hora de entrada.

Usa el estado

Para usar la hora que el usuario seleccionó en un selector de hora, pasa el TimePickerState apropiado a tu función onConfirm. El elemento superior componible puede acceder a la hora seleccionada a través de TimePickerState.hour y TimePickerState.minute.

En el siguiente fragmento, se muestra cómo hacerlo:

@Composable
fun DialUseStateExample(
    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,
    )

    Column {
        TimePicker(
            state = timePickerState,
        )
        Button(onClick = onDismiss) {
            Text("Dismiss picker")
        }
        Button(onClick = { onConfirm(timePickerState) }) {
            Text("Confirm selection")
        }
    }
}

Luego, puedes llamar al elemento componible de la siguiente manera:

var selectedTime: TimePickerState? by remember { mutableStateOf(null) }

// ...

DialUseStateExample(
    onDismiss = {
        showDialExample = false
    },
    onConfirm = {
            time ->
        selectedTime = time
        showDialExample = false
    },
)

// ...

if (selectedTime != null) {
    val cal = Calendar.getInstance()
    cal.set(Calendar.HOUR_OF_DAY, selectedTime!!.hour)
    cal.set(Calendar.MINUTE, selectedTime!!.minute)
    cal.isLenient = false
    Text("Selected time = ${formatter.format(cal.time)}")
} else {
    Text("No time selected.")
}

Para obtener más detalles, consulta la implementación completa en la app de fragmentos.

Recursos adicionales