2012-11-14 28 views
6

Używam DatePickerDialog i próbuję ustawić daty minimalne i maksymalne, aby użytkownik mógł wybrać tylko datę w ciągu ostatnich 24 godzin lub następnych 24 godzin.Wyjątek NullPointerException podczas korzystania z DatePicker setMaxDate() w DatePickerDialog

Oto kod. (Należy pamiętać, że to tylko stara się ustawić Min/Max zasięg jeśli działa na Androidzie 3.0 lub nowszym.)

private void showDatePickerDialog() { 
    DatePickerDialog.OnDateSetListener listener = new DatePickerDialog.OnDateSetListener() { 
     @Override 
     public void onDateSet(DatePicker view, int year, int monthOfYear, 
           int dayOfMonth) { 
      calendar.set(Calendar.YEAR, year); 
      calendar.set(Calendar.MONTH, monthOfYear); 
      calendar.set(Calendar.DAY_OF_MONTH, dayOfMonth); 
      onCalendarChanged(); 
     } 
    }; 

    DatePickerDialog dialog = new DatePickerDialog(this, 
                listener, 
                calendar.get(Calendar.YEAR), 
                calendar.get(Calendar.MONTH), 
                calendar.get(Calendar.DAY_OF_MONTH)); 
    setDatePickerDialogRange(dialog); 
    dialog.show(); 
} 

@SuppressLint("NewApi") 
private void setDatePickerDialogRange(DatePickerDialog dialog) { 
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) { 
     DatePicker picker = dialog.getDatePicker(); 
     long oneDayMilliseconds = 24 * 60 * 60 * 1000; 
     long nowMilliseconds = new Date().getTime(); 
     long minDate = nowMilliseconds - oneDayMilliseconds; 
     long maxDate = nowMilliseconds + oneDayMilliseconds; 
     picker.setMinDate(minDate); 
     picker.setMaxDate(maxDate); 
    } 
} 

Działa to dobrze, gdy uruchomiony na urządzeniu 2.2, ale na urządzeniu 4.0.4 (Galaxy Tab 2 7.0), otrzymuję ten wyjątek:

11-14 07:58:08.917: E/AndroidRuntime(16611): FATAL EXCEPTION: main 
11-14 07:58:08.917: E/AndroidRuntime(16611): java.lang.NullPointerException 
11-14 07:58:08.917: E/AndroidRuntime(16611): at android.widget.CalendarView.onScroll(CalendarView.java:910) 
11-14 07:58:08.917: E/AndroidRuntime(16611): at android.widget.CalendarView.access$600(CalendarView.java:74) 
11-14 07:58:08.917: E/AndroidRuntime(16611): at android.widget.CalendarView$2.onScroll(CalendarView.java:771) 
11-14 07:58:08.917: E/AndroidRuntime(16611): at android.widget.AbsListView.invokeOnItemScrollListener(AbsListView.java:1391) 
11-14 07:58:08.917: E/AndroidRuntime(16611): at android.widget.ListView.layoutChildren(ListView.java:1705) 
11-14 07:58:08.917: E/AndroidRuntime(16611): at android.widget.AbsListView.onLayout(AbsListView.java:2040) 
11-14 07:58:08.917: E/AndroidRuntime(16611): at android.view.View.layout(View.java:11330) 
11-14 07:58:08.917: E/AndroidRuntime(16611): at android.view.ViewGroup.layout(ViewGroup.java:4235) 
11-14 07:58:08.917: E/AndroidRuntime(16611): at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1644) 
11-14 07:58:08.917: E/AndroidRuntime(16611): at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1502) 
11-14 07:58:08.917: E/AndroidRuntime(16611): at android.widget.LinearLayout.onLayout(LinearLayout.java:1415) 
11-14 07:58:08.917: E/AndroidRuntime(16611): at android.view.View.layout(View.java:11330) 
11-14 07:58:08.917: E/AndroidRuntime(16611): at android.view.ViewGroup.layout(ViewGroup.java:4235) 
11-14 07:58:08.917: E/AndroidRuntime(16611): at android.widget.FrameLayout.onLayout(FrameLayout.java:431) 
11-14 07:58:08.917: E/AndroidRuntime(16611): at android.view.View.layout(View.java:11330) 
11-14 07:58:08.917: E/AndroidRuntime(16611): at android.view.ViewGroup.layout(ViewGroup.java:4235) 
11-14 07:58:08.917: E/AndroidRuntime(16611): at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1644) 
11-14 07:58:08.917: E/AndroidRuntime(16611): at android.widget.LinearLayout.layoutHorizontal(LinearLayout.java:1633) 
11-14 07:58:08.917: E/AndroidRuntime(16611): at android.widget.LinearLayout.onLayout(LinearLayout.java:1417) 
11-14 07:58:08.917: E/AndroidRuntime(16611): at android.view.View.layout(View.java:11330) 
11-14 07:58:08.917: E/AndroidRuntime(16611): at android.view.ViewGroup.layout(ViewGroup.java:4235) 
11-14 07:58:08.917: E/AndroidRuntime(16611): at android.widget.FrameLayout.onLayout(FrameLayout.java:431) 
11-14 07:58:08.917: E/AndroidRuntime(16611): at android.view.View.layout(View.java:11330) 
11-14 07:58:08.917: E/AndroidRuntime(16611): at android.view.ViewGroup.layout(ViewGroup.java:4235) 
11-14 07:58:08.917: E/AndroidRuntime(16611): at android.widget.FrameLayout.onLayout(FrameLayout.java:431) 
11-14 07:58:08.917: E/AndroidRuntime(16611): at android.view.View.layout(View.java:11330) 
11-14 07:58:08.917: E/AndroidRuntime(16611): at android.view.ViewGroup.layout(ViewGroup.java:4235) 
11-14 07:58:08.917: E/AndroidRuntime(16611): at android.widget.FrameLayout.onLayout(FrameLayout.java:431) 
11-14 07:58:08.917: E/AndroidRuntime(16611): at android.view.View.layout(View.java:11330) 
11-14 07:58:08.917: E/AndroidRuntime(16611): at android.view.ViewGroup.layout(ViewGroup.java:4235) 
11-14 07:58:08.917: E/AndroidRuntime(16611): at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1644) 
11-14 07:58:08.917: E/AndroidRuntime(16611): at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1502) 
11-14 07:58:08.917: E/AndroidRuntime(16611): at android.widget.LinearLayout.onLayout(LinearLayout.java:1415) 
11-14 07:58:08.917: E/AndroidRuntime(16611): at android.view.View.layout(View.java:11330) 
11-14 07:58:08.917: E/AndroidRuntime(16611): at android.view.ViewGroup.layout(ViewGroup.java:4235) 
11-14 07:58:08.917: E/AndroidRuntime(16611): at android.widget.FrameLayout.onLayout(FrameLayout.java:431) 
11-14 07:58:08.917: E/AndroidRuntime(16611): at android.view.View.layout(View.java:11330) 
11-14 07:58:08.917: E/AndroidRuntime(16611): at android.view.ViewGroup.layout(ViewGroup.java:4235) 
11-14 07:58:08.917: E/AndroidRuntime(16611): at android.widget.FrameLayout.onLayout(FrameLayout.java:431) 
11-14 07:58:08.917: E/AndroidRuntime(16611): at android.view.View.layout(View.java:11330) 
11-14 07:58:08.917: E/AndroidRuntime(16611): at android.view.ViewGroup.layout(ViewGroup.java:4235) 
11-14 07:58:08.917: E/AndroidRuntime(16611): at android.widget.FrameLayout.onLayout(FrameLayout.java:431) 
11-14 07:58:08.917: E/AndroidRuntime(16611): at android.view.View.layout(View.java:11330) 
11-14 07:58:08.917: E/AndroidRuntime(16611): at android.view.ViewGroup.layout(ViewGroup.java:4235) 
11-14 07:58:08.917: E/AndroidRuntime(16611): at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1548) 
11-14 07:58:08.917: E/AndroidRuntime(16611): at android.view.ViewRootImpl.handleMessage(ViewRootImpl.java:2505) 
11-14 07:58:08.917: E/AndroidRuntime(16611): at android.os.Handler.dispatchMessage(Handler.java:99) 
11-14 07:58:08.917: E/AndroidRuntime(16611): at android.os.Looper.loop(Looper.java:137) 
11-14 07:58:08.917: E/AndroidRuntime(16611): at android.app.ActivityThread.main(ActivityThread.java:4514) 
11-14 07:58:08.917: E/AndroidRuntime(16611): at java.lang.reflect.Method.invokeNative(Native Method) 
11-14 07:58:08.917: E/AndroidRuntime(16611): at java.lang.reflect.Method.invoke(Method.java:511) 
11-14 07:58:08.917: E/AndroidRuntime(16611): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:790) 
11-14 07:58:08.917: E/AndroidRuntime(16611): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:557) 
11-14 07:58:08.917: E/AndroidRuntime(16611): at dalvik.system.NativeStart.main(Native Method) 

To dzieje się natychmiast. DatePickerDialog nigdy nie jest wyświetlany.

Jeśli skomentuję linię setMaxDate(), to działa poprawnie. W tym przypadku przestrzegana jest minimalna data.

Jeśli zmienię to na setMaxDate(nowMilliseconds), nadal otrzymuję wyjątek NullPointerException.

+1

Z ciekawości, czy urządzenie jest ustawione na strefę czasową GMT? – iTurki

+0

Urządzenie jest ustawione na amerykański standardowy czas standardowy (GMT-5: 00). Właśnie zmieniłem strefę czasową na GMT i nadal otrzymuję NPE. –

+0

JFYI Skopiowałem twój kod do projektu testowego i uruchomiłem go poprawnie. Uruchomiłem go w emulatorze SDK 16. – Luis

Odpowiedz

0

spróbować wymienić:

setDatePickerDialogRange(dialog); 
dialog.show(); 

do:

dialog.show(); 
someView.post(new Runnable() { 
    public void run() { 
    setDatePickerDialogRange(dialog); 
    } 
}); 

(gdzie pewne View lub Handler jeśli masz jeden)

To opóźni wezwanie do setDatePickerDialogRange() aż po wyrenderowaniu okna dialogowego i może to być obejście problemu.

+0

Dobry pomysł, ale to nie pomogło. Nadal dostaję NPE. Jeśli spróbuję 'postDelayed (r, 2000)', to okno dialogowe wyświetla się na kilka sekund, ale NPE, gdy Runnable działa. –

+0

@KristopherJohnson: Cóż, drat. Wygląda na to, że programista nie przetestował tego scenariusza. Podejrzewam, że jesteś spieprzony. Utwórz przykładowy projekt, opublikuj go na http://b.android.com i miej nadzieję, że zostanie naprawiony pewnego dnia ... – CommonsWare

10

Pracowałem nad tym od dłuższego czasu. To jest błąd w systemie Android. Wystarczy wyłączyć widoku kalendarza i będzie dobrze:

picker.setCalendarViewShown(false); 
+0

Czy jest jakiś warunek, aby sprawdzić, czy "możemy" pokazać widok kalendarza, aby się nie zawiesił? Nie chcę wyłączać widoku kalendarza dla wszystkich, ponieważ działa dobrze dla większości użytkowników. –

+0

Miałem ten sam problem w KITKAT (API 19), i to działa! Dzięki. if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.KITKAT) { picker.setCalendarViewShown (fałsz); } – Herman

0
I have seen an issue.. 

DatePicker setMinDate() i setMaxDate() nie działają, gdy nowy termin jest taki sam jak stary rok min/max daty

proszę zapoznaj się z linkiem poniżej. Bugs on DatePicker setMinDate() and setMaxDate()

+2

Czy to wyjaśnia wyjątek NullPointerException? –

0

To działało> = API 19. Nie wiem, czy działa pod. Dzięki @JGGerrits.

Calendar min = (Calendar) minDate.clone(); 
Calendar max = (Calendar) maxDate.clone(); 
Calendar selected = (Calendar) selectedDate.clone(); 
min.set(Calendar.HOUR_OF_DAY, 0); 
max.set(Calendar.HOUR_OF_DAY, 23); 
selected.set(Calendar.HOUR_OF_DAY, 12); 

DatePickerDialog datePickerDialog = 
     new DatePickerDialog(context, callBack, selected); 

if(Build.VERSION.SDK_INT <= Build.VERSION_CODES.KITKAT) { 
    datePickerDialog.getDatePicker().setCalendarViewShown(false); 
} 

datePickerDialog.getDatePicker().setMinDate(min.getTimeInMillis()); 
datePickerDialog.getDatePicker().setMaxDate(max.getTimeInMillis()); 
datePickerDialog.show(); 
Powiązane problemy