Resolución de Problemas con DatePicker y TimePicker en Android

El archivo de布局 se presenta de la siguiente manera:

<?xml version="1.0" encoding="UTF-8" ?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center_horizontal"
    android:orientation="vertical">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Selecciona fecha y hora:"
        android:textSize="20dp" />

    <DatePicker
        android:id="@+id/seleccionadorFecha"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:datePickerMode="calendar"
        android:maxDate="12/30/2025" />

    <TimePicker
        android:id="@+id/seleccionadorHora"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

</LinearLayout>

La clase principal implementa la funcionalidad de mostrar la fecha y hora seleccionadas mediante un Toast:

public class SelectorTiempoActivity extends Activity {

    private int anio;
    private int mes;
    private int dia;
    private int hora;
    private int minuto;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.layout_selector_tiempo);
        
        DatePicker selectorFecha = findViewById(R.id.seleccionadorFecha);
        TimePicker selectorHora = findViewById(R.id.seleccionadorHora);
        
        Calendar calendario = Calendar.getInstance();
        anio = calendario.get(Calendar.YEAR);
        mes = calendario.get(Calendar.MONTH);
        dia = calendario.get(Calendar.DAY_OF_MONTH);
        hora = calendario.get(Calendar.HOUR);
        minuto = calendario.get(Calendar.MINUTE);

        // Inicialización del DatePicker con el listener correspondiente
        selectorFecha.init(anio, mes, dia, new DatePicker.OnDateChangedListener() {
            @Override
            public void onDateChanged(DatePicker vista, int anioSeleccionado, int mesSeleccionado, int diaSeleccionado) {
                SelectorTiempoActivity.this.anio = anioSeleccionado;
                SelectorTiempoActivity.this.mes = mesSeleccionado;
                SelectorTiempoActivity.this.dia = diaSeleccionado;
                // Mostrar la fecha actual
                mostrarFechaHora(anio, mes, dia, hora, minuto);
            }
        });

        selectorHora.setCurrentHour(hora);
        selectorHora.setCurrentMinute(minuto);
        selectorHora.setOnTimeChangedListener(new TimePicker.OnTimeChangedListener() {
            @Override
            public void onTimeChanged(TimePicker vista, int horaDelDia, int minutoSeleccionado) {
                SelectorTiempoActivity.this.hora = horaDelDia;
                SelectorTiempoActivity.this.minuto = minutoSeleccionado;
                mostrarFechaHora(anio, mes, dia, hora, minuto);
            }
        });
    }

    private void mostrarFechaHora(int anio, int mes, int dia, int hora, int minuto) {
        String mensaje = String.format("Fecha y hora seleccionadas: %s-%s-%s %s:%s", 
                                      anio, mes, dia, hora, minuto);
        Toast.makeText(this, mensaje, Toast.LENGTH_SHORT).show();
    }
}

El problema encontrado es que, aunque en el archivo XML se especificó el atributo android:maxDate="12/30/2025", el componente aún permitía seleccionar fechas posteriores a 2025, llegando hasta el año 2100.

Sin embargo, al modificar el archivo de布局 y utilizar un modo de selección diferente, el atributo maxDate funcionó correctamente:

<DatePicker
        android:id="@+id/seleccionadorFecha"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:calendarViewShown="false"
        android:datePickerMode="spinner"
        android:maxDate="12/30/2025"
        android:spinnersShown="true" />

Tras investigar sin encontrar una solución definitiva, se recordó que muchos atributos XML tienen métodos correspondientes en Java. Por lo tanto, se ajustó el código para utilizar el modo de calendario con android:datePickerMode="calendar" y se implementó el método setMaxDate(Long maxDate) en el código Java:

<DatePicker
        android:id="@+id/seleccionadorFecha"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:datePickerMode="calendar" />

calendario.set(2025, 11, 11);
selectorFecha.setMaxDate(calendario.getTimeInMillis());

Este enfoque cumplió con el objetivo deseado.

Se observó que otros atributos como android:startYear, android:endYear, android:maxDate y android:minDate presentan comportamientos similarse.

Actualmente no se ha encontrado una explicación definitiva para este comportamiento. Una interpretación simple sugiere que al utilizar atributos XML, es necesario ajustarse al modo spinner para que funcionen correctamente.

Etiquetas: Android datepicker TimePicker UI CalendarView

Publicado el 8-7 19:24