Selectores

Android proporciona controles para que el usuario seleccione una hora o una fecha como diálogos listos para usar. Cada selector ofrece controles para seleccionar cada parte de la hora (hora, minuto, a.m./p.m.) o de la fecha (mes, día, año). 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.

Te recomendamos que uses DialogFragment para alojar cada selector de fecha y hora. 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 celulares o como parte incorporada del diseño en pantallas grandes.

Aunque DialogFragment se agregó por primera vez a la plataforma en Android 3.0 (nivel de API 11), si tu app es compatible con versiones de Android anteriores a 3.0 (incluso a partir de Android 1.6), puedes usar la clase DialogFragment disponible en la biblioteca de compatibilidad para retrocompatibilidad.

Nota: En las siguientes muestras de código, se detalla cómo crear diálogos para un selector de hora y uno de fechas mediante las API de biblioteca de compatibilidad para DialogFragment. Si la minSdkVersion de tu app es 11 o posterior, puedes usar la versión de la plataforma de DialogFragment.

Las clases clave son las siguientes:

También puedes consultar la Descripción general de los fragmentos.

Cómo crear un selector de hora

Para mostrar un TimePickerDialog usando DialogFragment, debes definir una clase de fragmento que extienda DialogFragment y mostrar un TimePickerDialog del método onCreateDialog() del fragmento.

Nota: Si tu app admite versiones anteriores a Android 3.0, asegúrate de haber configurado tu proyecto de Android con la biblioteca de compatibilidad, como se describe en Cómo configurar un proyecto para usar una biblioteca.

Cómo extender DialogFragment para un selector de hora

A fin de definir un DialogFragment para un TimePickerDialog, debes hacer lo siguiente:

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 chosen by the user
    }
}

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 chosen by the user
    }
}

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

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

Cómo mostrar el selector de hora

Cuando hayas definido un DialogFragment como el que se muestra más arriba, puedes mostrar el selector de hora creando una instancia del DialogFragment y llamando a show().

Por ejemplo, a continuación se muestra un botón que, cuando se hace clic en él, llama a un método para mostrar el diálogo:

<Button
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="@string/pick_time"
    android:onClick="showTimePickerDialog" />

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

Kotlin

fun showTimePickerDialog(v: View) {
    TimePickerFragment().show(supportFragmentManager, "timePicker")
}

Java

public void showTimePickerDialog(View v) {
    DialogFragment newFragment = new TimePickerFragment();
    newFragment.show(getSupportFragmentManager(), "timePicker");
}

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

Precaución: Si tu app admite versiones inferiores a Android 3.0, asegúrate de llamar a getSupportFragmentManager() para adquirir una instancia de FragmentManager. También asegúrate de que la actividad que muestra el selector de hora extienda FragmentActivity en lugar de la clase Activity estándar.

Cómo crear un selector de fecha

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

Para mostrar un DatePickerDialog usando DialogFragment, debes definir una clase de fragmento que extienda DialogFragment y mostrar un DatePickerDialog del método onCreateDialog() del fragmento.

Cómo extender DialogFragment para un selector de fecha

A fin de definir un DialogFragment para un DatePickerDialog, debes hacer lo siguiente:

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(activity, this, year, month, day)
    }

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

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(getActivity(), this, year, month, day);
    }

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

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

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

Cómo mostrar el selector de fecha

Cuando hayas definido un DialogFragment como el que se muestra más arriba, puedes mostrar el selector de fecha creando una instancia del DialogFragment y llamando a show().

Por ejemplo, a continuación se muestra un botón que, cuando se hace clic en él, llama a un método para mostrar el diálogo:

<Button
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="@string/pick_date"
    android:onClick="showDatePickerDialog" />

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

Kotlin

fun showDatePickerDialog(v: View) {
    val newFragment = DatePickerFragment()
    newFragment.show(supportFragmentManager, "datePicker")
}

Java

public void showDatePickerDialog(View v) {
    DialogFragment newFragment = new DatePickerFragment();
    newFragment.show(getSupportFragmentManager(), "datePicker");
}

Este método llama a show() en una instancia nueva del DialogFragment definido anteriormente. 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

Android 8.0 presenta Autofill Framework, que permite a los usuarios guardar datos que luego pueden usarse 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 permitiría a los usuarios ingresar o cambiar 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 objeto EditText, que puede mostrar el valor en ese caso.

De forma nativa, un objeto EditText espera autocompletar datos del tipo AUTOFILL_TYPE_TEXT. Por el contrario, los servicios de autocompletado deben guardar los datos como AUTOFILL_TYPE_DATE para poder crear una representación adecuada de ellos. A fin de resolver la inconsistencia en los tipos, se recomienda 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.

Para crear una subclase de EditText que pueda procesar los valores del tipo AUTOFILL_TYPE_DATE, debes seguir estos pasos:

  1. Crea una clase que se herede de EditText.
  2. Implementa el método getAutofillType(), que debe mostrar AUTOFILL_TYPE_DATE.
  3. Implementa el método getAutofillValue(), que debe mostrar un objeto AutofillValue que represente la fecha en milisegundos. Para crear el objeto que se muestra, usa el método forDate() para generar un objeto AutofillValue.
  4. Implementa el método autofill(). Este método proporciona la lógica para procesar el parámetro AutofillValue, que es del tipo AUTOFILL_TYPE_DATE. Para procesar el parámetro, crea una representación de string adecuada, 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 debe actualizar la propiedad text con una representación de string del valor que el usuario seleccionó en el selector.

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

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