setMaxDate() 在 Lollipop 5.0.1 android 上无法正常工作,需要适当的解决方案

Posted

技术标签:

【中文标题】setMaxDate() 在 Lollipop 5.0.1 android 上无法正常工作,需要适当的解决方案【英文标题】:setMaxDate() not working perfectly on Lollipop 5.0.1 android and need proper solution 【发布时间】:2017-10-10 00:53:29 【问题描述】:

即使在将setMaxDate() 应用到日期选择器之后,我仍然可以在棒棒糖 5.0.1 上选择禁用的日期。该代码适用于除棒棒糖 5.0.1 之外的所有其他版本的 android

在此处通过设置setMaxDate() 限制日期后,用户应该无法选择禁用的日期。如何以编程方式为DatePicker 实现这一目标?

我已经尝试了以下代码:-

datePickerDialog = new DatePickerDialog(myContext, new DatePickerDialog.OnDateSetListener() 
        @Override
        public void onDateSet(DatePicker view, int year, int month, int dayOfMonth) 
        
    , mYear, mMonth, mDay);
    datePickerDialog.getDatePicker().setMaxDate(System.currentTimeMillis());
    datePickerDialog.setCanceledOnTouchOutside(true);
    datePickerDialog.setCancelable(true);
    datePickerDialog.show();

我也尝试了以下解决方案,但这些似乎不起作用:-

datePickerDialog.getDatePicker().setMaxDate(System.currentTimeMillis());

Calendar maxCal = Calendar.getInstance();
datePickerDialog.getDatePicker().setMaxDate(maxCal.getTimeInMillis());

Date maxDate = new Date();
datePickerDialog.getDatePicker().setMaxDate(maxDate.getTime());

请向setMaxDate()提供适用于棒棒糖的解决方案。

或者,如果您有任何其他答案,请尝试包含官方报价和资源或链接(如 android 开发者网站),如果您知道简要详细信息。提前致谢。

【问题讨论】:

能否提及设备制造商名称? 它可能与 System.currentTimeInMillis() 及其实现有关。你试过 Calendar.getInstance().getTimeInMillis() 吗? @RahulKhurana 我的手机是三星。 @Opiatefuchs 我不这么认为它的长期价值。此外,我提到它在其他版本中运行良好。 不要尝试让它工作。 DatePicker 会因每个设备和 Android 版本而异,有些日期显示为禁用,而有些则让您仍然选择它们,而其他人则完全忽略这些设置。确保检查返回的值,和/或切换到其他库(google / github search)。来源:在这上面浪费了足够的时间。 【参考方案1】:

正如在 cmets 中已经指出的那样,对于这个有问题的日历并没有真正完美的解决方案(在 Android 5.0 上,您可以选择无效的日期,而在某些三星设备上,会出现奇怪的行为:按下后退按钮实际上是在选择一个日期等等我真的不记得了)。但是,当您可以通过检查其有效性并在失败时显示Toast 来选择无效日期时,我解决了该问题。这不会阻止用户实际选择无效日期,而是强制用户选择有效日期以继续使用应用程序。

   DatePickerDialog dialog = new DatePickerDialog(getActivity(), mOnDateSetListener, year, month, day) 
        private boolean allowClose = false;

        @Override
        public void onBackPressed() 
            allowClose = true;
            super.onBackPressed();
        

        @Override
        public void onClick(DialogInterface dialog, int which) 
            allowClose = true;
            if (which == DialogInterface.BUTTON_POSITIVE && !validate()) 
                allowClose = false;
                Toast.makeText(getContext(), R.string.invalid_date, Toast.LENGTH_SHORT).show();
            
            if (allowClose) 
                super.onClick(dialog, which);
            
        

        @Override
        public void dismiss() 
            if (allowClose) 
                super.dismiss();
            
        
    ;

通过使用它,您可以确保如果用户选择了无效的日期,您将在您按下Ok 按钮时向他发出适当的警告消息并阻止日历关闭。应该创建 validate 函数以满足您的需求,但我认为我所拥有的就可以了:

private boolean validate() 
    if (this.getDialog() instanceof DatePickerDialog) 
        DatePicker datePicker = ((DatePickerDialog) this.getDialog()).getDatePicker();
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.YEAR, datePicker.getYear());
        calendar.set(Calendar.MONTH, datePicker.getMonth());
        calendar.set(Calendar.DAY_OF_MONTH, datePicker.getDayOfMonth());
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MILLISECOND, 0);
        boolean valid = false;
        Calendar minCalendar = Calendar.getInstance();
        minCalendar.setTimeInMillis(datePicker.getMinDate());
        Calendar maxCalendar = Calendar.getInstance();
        maxCalendar.setTimeInMillis(datePicker.getMaxDate());
        if (DateUtils.in(calendar.getTime(), minCalendar.getTime(), maxCalendar.getTime())) 
            valid = true;
        
        return valid;
    
    return false;

最后,我不保证这是最好的解决方案,但我已经使用了它并且没有收到任何用户的投诉。

【讨论】:

感谢您的吐司建议。我知道并且已经这样做了。如果可能,需要解决方案而不是其他方式来满足要求。 也许你可以通过继承 DatePicker 来实现你想要的,但我必须进一步调查。在我有时间尝试子类化版本之前,我将把它放在这里。【参考方案2】:

是的,我为 datePicker 找到了一个库 wdullaer/MaterialDateTimePicker,它在 lollipop 5.0.1完美运行,就像在其他 API 版本。

解决方案库的链接是Click Here For MaterialDateTimePicker

通过在build.gradle(app) 文件的dependencies... 中添加以下行来添加此库。

compile 'com.wdullaer:materialdatetimepicker:3.2.1'

然后根据需要实现以下代码:-

MainActivity mainActivity = (MainActivity) myContext;
    final DatePickerDialog dpd = DatePickerDialog.newInstance(
            new DatePickerDialog.OnDateSetListener() 
                @Override
                public void onDateSet(DatePickerDialog view, int year, int monthOfYear, int dayOfMonth) 
                    //To do your task here
                
            ,
            mYear,
            mMonth,
            mDay
    );
    dpd.setVersion(DatePickerDialog.Version.VERSION_2);
    dpd.setMaxDate(Calendar.getInstance());
    dpd.show(mainActivity.getFragmentManager(), "Datepickerdialog");

【讨论】:

【参考方案3】:

您需要添加日历实例并将其用作 maxDate。请参考下面代码中添加的行。

datePickerDialog = new DatePickerDialog(myContext, new DatePickerDialog.OnDateSetListener() 
    @Override
    public void onDateSet(DatePicker view, int year, int month, int dayOfMonth) 
    
, mYear, mMonth, mDay);

Calendar maxCal = Calendar.getInstance();

datePickerDialog.getDatePicker().setMaxDate(maxCal.getTimeInMillis());
datePickerDialog.setCanceledOnTouchOutside(true);
datePickerDialog.setCancelable(true);
datePickerDialog.show();

【讨论】:

不工作.. 你能在你身边检查一下,这对棒棒糖有用吗? 是的,它适用于棒棒糖。已经检查过了。您仍然可以使用此代码选择比今天更大的日期吗? 是的,我可以选择比今天更大的。我有棒棒糖 5.0.1 的真实设备。

以上是关于setMaxDate() 在 Lollipop 5.0.1 android 上无法正常工作,需要适当的解决方案的主要内容,如果未能解决你的问题,请参考以下文章

HttpClient 在 Android 5.0 Lollipop 中因握手失败而失败

应用程序如何检测状态栏颜色(Android 5.0 Lollipop)?

Android 5.0 Lollipop介绍

Android 5.0 Lollipop 上的 UnsatisfiedLinkError

如何在带有 Android 5.0 Lollipop 的代码(不是 xml)中以编程方式使用 RippleDrawable?

Android Studio - 如何在 webview Lollipop 中上传文件 (Android 5.0)