Agrega selectores a tu app

Prueba hacerlo con Compose
Jetpack Compose es el kit de herramientas de IU recomendado para Android. Obtén información para agregar componentes en Compose.

Android proporciona controles para que el usuario seleccione una hora o una fecha como diálogos listos para usar. Estos selectores ofrecen controles para seleccionar cada parte de la hora (hora, minuto, a.m./p.m.) o de la fecha (mes, día, año).

Ejemplo del selector de hora de material.io
Figura 1. Selección de hora en un selector de calendario para dispositivos móviles

El uso de estos selectores ayuda a garantizar que tus usuarios puedan elegir una hora o una fecha válidas, con el formato correcto y ajustadas a su configuración regional.

Ejemplo de un selector de fecha modal de material.io
Figura 2. Selector de fecha modal

Te recomendamos que uses DialogFragment para alojar cada selector de hora o fecha. DialogFragment administra el ciclo de vida del diálogo y te permite mostrar los selectores en diferentes configuraciones de diseño, como en un diálogo básico en teléfonos o como parte incorporada del diseño en pantallas grandes.

Cómo crear un selector de hora

Para mostrar un TimePickerDialog con DialogFragment, define una clase de fragmento que extienda DialogFragment y muestra un TimePickerDialog desde el método onCreateDialog() del fragmento.

Cómo extender DialogFragment para un selector de hora

Para definir un DialogFragment para un TimePickerDialog, haz lo siguiente:

  • Define el método onCreateDialog() para mostrar una instancia de TimePickerDialog.
  • Implementa la TimePickerDialog.OnTimeSetListener interfaz para recibir una devolución de llamada cuando el usuario configure la hora.

Por ejemplo:

Kotlin

class TimePickerFragment : DialogFragment(), TimePickerDialog.OnTimeSetListener {

    override fun onCreateDialog(savedInstanceState: Bundle): Dialog {
        // Use the current time as the default values for the picker.
        val c = Calendar.getInstance()
        val hour = c.get(Calendar.HOUR_OF_DAY)
        val minute = c.get(Calendar.MINUTE)

        // Create a new instance of TimePickerDialog and return it.
        return TimePickerDialog(activity, this, hour, minute, DateFormat.is24HourFormat(activity))
    }

    override fun onTimeSet(view: TimePicker, hourOfDay: Int, minute: Int) {
        // Do something with the time the user picks.
    }
}

Java

public static class TimePickerFragment extends DialogFragment
                            implements TimePickerDialog.OnTimeSetListener {

    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        // Use the current time as the default values for the picker.
        final Calendar c = Calendar.getInstance();
        int hour = c.get(Calendar.HOUR_OF_DAY);
        int minute = c.get(Calendar.MINUTE);

        // Create a new instance of TimePickerDialog and return it.
        return new TimePickerDialog(getActivity(), this, hour, minute,
                DateFormat.is24HourFormat(getActivity()));
    }

    public void onTimeSet(TimePicker view, int hourOfDay, int minute) {
        // Do something with the time the user picks.
    }
}

Consulta la clase TimePickerDialog para obtener información sobre los argumentos del constructor.

Ahora, solo necesitas un evento que agregue una instancia de este fragmento a tu actividad.

Cómo mostrar el selector de hora

Después de definir un DialogFragment como el del ejemplo anterior, puedes mostrar el selector de hora creando una instancia de DialogFragment y llamando al método show().

Por ejemplo, este es un botón que, cuando se presiona, llama a un método para mostrar el diálogo:

<Button
    android:id="@+id/pickTime"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="Pick time" />

Cuando el usuario presiona este botón, el sistema llama al siguiente método:

Kotlin

findViewById<Button>(R.id.pickTime).setOnClickListener {
    TimePickerFragment().show(supportFragmentManager, "timePicker")
}

Java

findViewById<Button>(R.id.pickTime).setOnClickListener {
    TimePickerFragment().show(supportFragmentManager, "timePicker");
}

Este método llama a show() en una instancia nueva de DialogFragment definida en el ejemplo anterior. El método show() requiere una instancia de FragmentManager y un nombre de etiqueta único para el fragmento.

Cómo crear un selector de fecha

Crear un DatePickerDialog es como crear un TimePickerDialog. La diferencia es el diálogo que creas para el fragmento.

Para mostrar un DatePickerDialog con DialogFragment, define una clase de fragmento que extienda DialogFragment y muestra un DatePickerDialog desde el método onCreateDialog() del fragmento.

Cómo extender DialogFragment para un selector de fecha

Para definir un DialogFragment para un DatePickerDialog, haz lo siguiente:

  • Define el método onCreateDialog() para mostrar una instancia de DatePickerDialog.
  • Implementa la DatePickerDialog.OnDateSetListener interfaz para recibir una devolución de llamada cuando el usuario configure la fecha.

Por ejemplo:

Kotlin

class DatePickerFragment : DialogFragment(), DatePickerDialog.OnDateSetListener {

    override fun onCreateDialog(savedInstanceState: Bundle): Dialog {
        // Use the current date as the default date in the picker.
        val c = Calendar.getInstance()
        val year = c.get(Calendar.YEAR)
        val month = c.get(Calendar.MONTH)
        val day = c.get(Calendar.DAY_OF_MONTH)

        // Create a new instance of DatePickerDialog and return it.
        return DatePickerDialog(requireContext(), this, year, month, day)

    }

    override fun onDateSet(view: DatePicker, year: Int, month: Int, day: Int) {
        // Do something with the date the user picks.
    }
}

Java

public static class DatePickerFragment extends DialogFragment
                            implements DatePickerDialog.OnDateSetListener {

    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        // Use the current date as the default date in the picker.
        final Calendar c = Calendar.getInstance();
        int year = c.get(Calendar.YEAR);
        int month = c.get(Calendar.MONTH);
        int day = c.get(Calendar.DAY_OF_MONTH);

        // Create a new instance of DatePickerDialog and return it.
        return new DatePickerDialog(requireContext(), this, year, month, day);
    }

    public void onDateSet(DatePicker view, int year, int month, int day) {
        // Do something with the date the user picks.
    }
}

Consulta la clase DatePickerDialog para obtener información sobre los argumentos del constructor.

Solo necesitas un evento que agregue una instancia de este fragmento a tu actividad.

Cómo mostrar el selector de fecha

Después de definir un DialogFragment como el del ejemplo anterior, puedes mostrar el selector de fecha creando una instancia de DialogFragment y llamando a show().

Por ejemplo, este es un botón que, cuando se presiona, llama a un método para mostrar el diálogo:

<Button
    android:id="@+id/pickDate"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="Pick date"/>

Cuando el usuario presiona este botón, el sistema llama al siguiente método:

Kotlin

findViewById<Button>(R.id.pickDate).setOnClickListener {
    val newFragment = DatePickerFragment()
    newFragment.show(supportFragmentManager, "datePicker")
}

Java

findViewById<Button>(R.id.pickDate).setOnClickListener {
    val newFragment = DatePickerFragment();
    newFragment.show(supportFragmentManager, "datePicker");
}

Este método llama a show() en una instancia nueva de DialogFragment definida en el ejemplo anterior. El método show() requiere una instancia de FragmentManager y un nombre de etiqueta único para el fragmento.

Cómo usar selectores con la función Autocompletar

En 2017, Android presentó el framework de Autocompletar, que permite a los usuarios guardar datos que se pueden usar para completar formularios en diferentes apps. Los selectores pueden ser útiles en situaciones de autocompletado, ya que proporcionan una IU que permite a los usuarios cambiar el valor de un campo que almacena datos de fecha y hora. Por ejemplo, en un formulario de tarjeta de crédito, un selector de fecha permite que los usuarios ingresen o cambien la fecha de vencimiento de su tarjeta de crédito.

Como los selectores son diálogos, no se muestran en una actividad junto con otros campos. Para mostrar los datos del selector cuando este no está visible, puedes usar otra vista, como un EditText, que puede mostrar el valor cuando el selector no está visible.

De forma nativa, un objeto EditText espera autocompletar datos de tipo AUTOFILL_TYPE_TEXT. Por el contrario, los servicios de autocompletado guardan los datos como AUTOFILL_TYPE_DATE para crear una representación adecuada de ellos. Para resolver la inconsistencia en los tipos, te recomendamos que crees una vista personalizada que se herede de EditText e implemente los métodos necesarios para procesar correctamente los valores del tipo AUTOFILL_TYPE_DATE.

Sigue estos pasos para crear una subclase de EditText que pueda controlar valores de tipo AUTOFILL_TYPE_DATE:

  1. Crea una clase que se herede de EditText.
  2. Implementa el getAutofillType() método, que muestra AUTOFILL_TYPE_DATE.
  3. Implementa el getAutofillValue() método, que muestra un AutofillValue objeto que representa la fecha en milisegundos. Para crear el objeto de devolución, usa el método para generar un objeto.forDate()AutofillValue
  4. Implementa el autofill() método. Este método proporciona la lógica para procesar el AutofillValue parámetro, que es del tipo AUTOFILL_TYPE_DATE. Para procesar el parámetro, crea una representación de string adecuada de él, como mm/yyyy. Usa la representación de string para configurar la propiedad text de tu vista.
  5. Implementa la funcionalidad que muestra un selector cuando el usuario desea editar la fecha en la subclase personalizada de EditText. La vista actualiza la propiedad text con una representación de string del valor que el usuario selecciona en el selector.

Para ver un ejemplo de una subclase de EditText que procesa AUTOFILL_TYPE_DATE valores, consulta la muestra de Autofill Framework en Java o Kotlin.

Para obtener más información sobre cómo probar la compatibilidad de autocompletado para tus vistas personalizadas, consulta Framework de Autocompletar.