2012-11-14 47 views
6

Ich verwende einen DatePickerDialog, und ich versuche, die minimalen und maximalen Daten so festzulegen, dass der Benutzer nur ein Datum innerhalb der letzten 24 Stunden oder 24 Stunden auswählen kann.NullPointerException bei Verwendung von DatePicker setMaxDate() in einem DatePickerDialog

Hier ist der Code. (Beachten Sie, dass es nur versucht, den Min-/Max-Bereich einzustellen, wenn auf Android 3.0 oder höher.)

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

Dies funktioniert gut, wenn sie auf einem 2,2-Gerät läuft, aber auf einem 4.0.4 Gerät (Galaxy Tab 2 7.0), bekomme ich diese Ausnahme:

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) 

Dies geschieht sofort. Der DatePickerDialog wird nie angezeigt.

Wenn ich die setMaxDate() Zeile kommentieren, dann funktioniert es gut. In diesem Fall wird das Mindestdatum eingehalten.

Wenn ich es in setMaxDate(nowMilliseconds) ändern, bekomme ich immer noch die NullPointerException.

+1

Aus Neugier, Ist das Gerät auf GMT-Zeitzone eingestellt? – iTurki

+0

Gerät ist auf US Eastern Standard Time (GMT-5: 00) eingestellt. Ich habe gerade seine Zeitzone auf GMT geändert, und ich bekomme immer noch die NPE. –

+0

JFYI Ich habe Ihren Code in ein Testprojekt kopiert und es läuft OK. Ich habe es im Emulator SDK 16 ausgeführt. – Luis

Antwort

0

Versuchen ersetzen:

setDatePickerDialogRange(dialog); 
dialog.show(); 

zu:

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

(wo einige View ist, oder ein Handler wenn Sie eine haben)

Dadurch wird der Anruf an setDatePickerDialogRange() verzögern, bis nachdem der Dialog gerendert wurde und möglicherweise eine Problemumgehung für Ihr Problem ist.

+0

Gute Idee, aber es hat nicht geholfen. Ich bekomme immer noch die NPE. Wenn ich ein 'postDelayed (r, 2000)' versuche, wird der Dialog für ein paar Sekunden angezeigt, aber NPE's, wenn das Runnable ausgeführt wird. –

+0

@KristopherJohnson: Nun, drat. Sieht so aus, als hätte der Entwickler dieses Szenario nicht getestet. Ich vermute, du bist verschissen. Erstelle ein Beispielprojekt, poste es auf http://b.android.com und hoffe, dass es eines Tages repariert wird ... – CommonsWare

10

Schon lange daran gearbeitet. Dies ist ein Fehler in Android. Schalten Sie einfach die Kalender-Ansicht und Sie werden fein:

picker.setCalendarViewShown(false); 
+0

Gibt es eine Bedingung, um zu prüfen, ob wir die Kalenderansicht "anzeigen" können, damit sie nicht abstürzt? Ich möchte nicht die Kalenderansicht für alle ausschalten, weil es für die meisten Benutzer funktioniert –

+0

Ich hatte das gleiche Problem in KITKAT (API 19), und das funktioniert! Vielen Dank. if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.KITKAT) { picker.setCalendarViewShown (false); } – Herman

0
I have seen an issue.. 

Datepicker setMinDate() und setMaxDate() funktionieren nicht, wenn der neue Termin im selben Jahr wie die alte min/max Datum ist

Bitte Verweisen Sie den Link unten. Bugs on DatePicker setMinDate() and setMaxDate()

+2

Erklärt dies die NullPointerException? –

0

Dies funktionierte> = API 19. Weiß nicht, ob funktioniert unter. Danke @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(); 
Verwandte Themen