2012-11-14 26 views
6

Tôi đang sử dụng DatePickerDialog và tôi đang cố gắng đặt ngày tối thiểu và tối đa sao cho người dùng chỉ có thể chọn ngày trong 24 giờ trước hoặc 24 giờ tiếp theo.NullPointerException khi sử dụng DatePicker setMaxDate() trong DatePickerDialog

Đây là mã. (Lưu ý rằng nó chỉ cố gắng để thiết lập min/phạm vi tối đa nếu chạy trên Android 3.0 hoặc cao hơn.)

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

này hoạt động tốt khi chạy trên một thiết bị 2.2, nhưng trên một thiết bị 4.0.4 (Galaxy Tab 2 7.0), tôi nhận ngoại lệ này:

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) 

Điều này xảy ra ngay lập tức. DatePickerDialog không bao giờ được hiển thị.

Nếu tôi nhận xét dòng setMaxDate() thì nó hoạt động tốt. Trong trường hợp này, ngày tối thiểu được tôn trọng.

Nếu tôi đổi thành setMaxDate(nowMilliseconds), tôi vẫn nhận được NullPointerException.

+1

Hết sức tò mò, Thiết bị có được đặt thành múi giờ GMT không? – iTurki

+0

Thiết bị được đặt thành Giờ chuẩn miền Đông Hoa Kỳ (GMT-5: 00). Tôi chỉ thay đổi múi giờ của nó thành GMT, và tôi vẫn nhận được NPE. –

+0

JFYI Tôi đã sao chép mã của bạn vào một dự án thử nghiệm và nó chạy OK. Tôi đã chạy nó trong giả lập SDK 16. – Luis

Trả lời

0

Hãy thử thay thế:

setDatePickerDialogRange(dialog); 
dialog.show(); 

tới:

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

(nơi là một số View, hoặc một Handler nếu có)

này sẽ trì hoãn việc gọi đến setDatePickerDialogRange() cho đến khi sau khi hộp thoại được hiển thị và có thể là giải pháp cho sự cố của bạn.

+0

Ý tưởng hay nhưng không hiệu quả. Tôi vẫn nhận được NPE. Nếu tôi thử một 'postDelayed (r, 2000)', thì hộp thoại sẽ hiển thị trong vài giây, nhưng NPE là khi Runnable chạy. –

+0

@KristopherJohnson: Vâng, drat. Có vẻ như nhà phát triển không thử nghiệm kịch bản này. Tôi nghi ngờ bạn đang say. Tạo một dự án mẫu, đăng nó lên http://b.android.com và hy vọng nó sẽ được khắc phục vào một ngày nào đó ... – CommonsWare

10

Đã làm việc về điều này trong một thời gian. Đây là lỗi trong Android. Chỉ cần tắt Lịch Xem và bạn sẽ bị phạt:

picker.setCalendarViewShown(false); 
+0

có điều kiện nào để kiểm tra xem liệu "có thể" hiển thị chế độ xem lịch để nó không bị lỗi không? Tôi không muốn tắt chế độ xem lịch cho tất cả mọi người vì nó hoạt động tốt cho hầu hết người dùng –

+0

Tôi đã gặp vấn đề tương tự trong KITKAT (API 19) và hoạt động này! Cảm ơn. if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.KITKAT) { picker.setCalendarViewShown (sai); } – Herman

0
I have seen an issue.. 

DatePicker setMinDate()setMaxDate() không hoạt động khi ngày mới là năm tương tự như các min/max ngày cũ

Hãy tham khảo liên kết bên dưới. Bugs on DatePicker setMinDate() and setMaxDate()

+2

Điều này có giải thích NullPointerException không? –

0

Tính năng này hoạt động> = API 19. Không biết liệu có hoạt động không. Cảm ơn @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(); 
Các vấn đề liên quan