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

Hay dos tipos de selectores de hora:

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

En la siguiente imagen, se muestra un ejemplo de un selector de hora de dial 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 selector de hora de dial y de entrada

Superficie de la API

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

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

Estado

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 diálogos. En los ejemplos de esta guía, no se usan diálogos. Para ver ejemplos que sí los usan, consulta la guía Diálogos para selectores de hora.

Selector de hora de dial

En este fragmento, se muestra cómo implementar un selector de hora de dial 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 el TimePickerState con la hora actual.
    • En este ejemplo, se usa java.util.Calendar. Habilita la expansión de sintaxis de la API de Java 8 y versiones posteriores en tu proyecto para usar java.time.LocalTime en todas las versiones de Android.
  • El elemento componible TimePicker 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 descartar el selector.

Esta implementación aparece de la siguiente manera:

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

Selector de hora de entrada

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

Consideraciones clave en esta implementación:

  • La estructura es esencialmente la misma que el selector de hora de dial, y la diferencia principal es el uso de 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:

Es un selector de hora de entrada. El usuario puede ingresar una hora con 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 adecuado a tu función onConfirm. Luego, el elemento componible superior puede acceder a la hora seleccionada a través de TimePickerState.hour y TimePickerState.minute.

En el siguiente fragmento de código, 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