【问题标题】:NullPointerException when using DatePicker setMaxDate() in a DatePickerDialog在 DatePickerDialog 中使用 DatePicker setMaxDate() 时出现 NullPointerException
【发布时间】:2017-06-01 03:47:43
【问题描述】:

我正在使用 DatePickerDialog,我正在尝试设置最小和最大日期,以便用户只能选择前 24 小时或接下来 24 小时内的日期。

这里是代码。 (请注意,如果在 Android 3.0 或更高版本上运行,它只会尝试设置最小/最大范围。)

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

这在 2.2 设备上运行时工作正常,但在 4.0.4 设备(Galaxy Tab 2 7.0)上,我得到这个异常:

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)

这会立即发生。 DatePickerDialog 永远不会显示。

如果我注释掉 setMaxDate() 行,那么它可以正常工作。在这种情况下,会遵守最短日期。

如果我将其更改为 setMaxDate(nowMilliseconds),我仍然会收到 NullPointerException。

【问题讨论】:

  • 出于好奇,设备是否设置为 GMT 时区?
  • 设备设置为美国东部标准时间 (GMT-5:00)。我刚刚将其时区更改为 GMT,我仍然得到 NPE。
  • JFYI 我已将您的代码复制到一个测试项目中,它运行正常。我已经在模拟器 SDK 16 中运行它。
  • @KristopherJohnson 你解决了这个问题吗?我也有同样的问题,但对我来说关闭日历视图对我来说不是一个好主意..
  • @GennadiiSaprykin 不,从未找到解决方法。刚刚决定不调用 setMaxDate()。

标签: android datepickerdialog


【解决方案1】:

已经为此工作了很长时间。这是Android中的一个错误。只需关闭日历视图就可以了:

picker.setCalendarViewShown(false);

【讨论】:

  • 是否有条件检查我们是否“可以”显示日历视图以使其不会崩溃?我不想为所有人关闭日历视图,因为它适用于大多数用户
  • 我在 KITKAT (API 19) 中遇到了同样的问题,这很有效!谢谢。 if(Build.VERSION.SDK_INT
【解决方案2】:

尝试替换:

setDatePickerDialogRange(dialog);
dialog.show();

到:

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

(其中someView 是一些View,或者Handler,如果有的话)

这将延迟对setDatePickerDialogRange() 的调用,直到呈现对话框之后,这可能是您的问题的解决方法。

【讨论】:

  • 好主意,但没有帮助。我仍然得到NPE。如果我尝试postDelayed(r, 2000),则对话框会显示几秒钟,但当 Runnable 运行时会显示 NPE。
  • @KristopherJohnson:好吧,废话。看起来开发人员没有测试这种情况。我怀疑你被搞砸了。创建一个示例项目,将其发布到b.android.com,并希望它有一天得到修复...
【解决方案3】:
I have seen an issue..

当新日期与旧的最小/最大日期相同的年份时,DatePicker setMinDate()setMaxDate() 不起作用

请参考以下链接。 Bugs on DatePicker setMinDate() and setMaxDate()

【讨论】:

  • 这是否解释了 NullPointerException?
【解决方案4】:

这工作> = API 19。不知道是否工作。 谢谢@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();

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-11-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多