在 Android 日期选择器中禁用特定日期

Posted

技术标签:

【中文标题】在 Android 日期选择器中禁用特定日期【英文标题】:Disable specific dates of day in Android date picker 【发布时间】:2016-06-06 13:39:03 【问题描述】:

我正在使用 datePicker,我可以通过以下代码禁用今天的最后几天和 30 天后的晚些时候:

DatePickerDialog datePicker = new DatePickerDialog();

             Calendar calender = Calendar.getInstance();
             long today = calender.getTimeInMillis();
             final long oneDay = 24 * 60 * 60 * 1000L;

             Date previousDays = new Date(today - 1000);
             datePicker.setMinDate(DateToCalendar(previousDays));

             Date nextMonth = new Date(today + 30 * oneDay);
             datePicker.setMaxDate(DateToCalendar(nextMonth));

如果我想禁用每个月的星期五,我该怎么做?

【问题讨论】:

【参考方案1】:

你可以使用这个库Material Date Time Picker,在这里你可以设置一个选项来显示特定的日期,例如:

datePicker.setSelectableDays(Calendar[] days)

并将Calendar 的数组作为包含所有可选日期的参数传递。

【讨论】:

非常感谢,这很好用。我不知道为什么标准的安卓系统如此有限。 如何通过上述库中的天数来禁用?假设如何禁用所有周末? 创建一个不包括周末的日期数组并将其作为可选日期传递。【参考方案2】:

使用自定义 DatePickerDialog

在 build.gradle 中添加这个

编译'com.wdullaer:materialdatetimepicker:3.5.1'

实施

DatePickerDialog.OnDateSetListener到你的班级

并导入

import com.wdullaer.materialdatetimepicker.date.DatePickerDialog; 而不是 'import android.app.DatePickerDialog;'

并添加此方法

 private void showDatePicker()  

    Calendar calendar = Calendar.getInstance();

    DatePickerDialog dpd = DatePickerDialog.newInstance(
            this,
            calendar.get(Calendar.YEAR),
            calendar.get(Calendar.MONTH),
            calendar.get(Calendar.DAY_OF_MONTH)
    );
    dpd.show(getActivity().getFragmentManager(), "DatePickerDialog");

    SimpleDateFormat sdf = new SimpleDateFormat("dd-MM-yyyy");
    String a = "07-03-2018"; // example

    java.util.Date date = null;

    try 
        date = sdf.parse(a);
     catch (ParseException e) 
        e.printStackTrace();
    

    calendar = dateToCalendar(date);
    System.out.println(calendar.getTime());

    List<Calendar> dates = new ArrayList<>();
    dates.add(calendar);
    Calendar[] disabledDays1 = dates.toArray(new Calendar[dates.size()]);
    dpd.setDisabledDays(disabledDays1);



    private Calendar dateToCalendar(Date date) 
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        return calendar;
    




@Override
public void onDateSet(DatePickerDialog view, int year, int monthOfYear, int dayOfMonth) 

    String date = dayOfMonth+"/"+(monthOfYear+1)+"/"+year;
    textview.setText(date);


调用 showDatePicker()。

多天

改变这个

     String[] holidays = "07-03-2018","05-03-2018","10-03-2018";

    java.util.Date date = null;

    for (int i = 0;i < holidays.length; i++) 

        try 
            date = sdf.parse(holidays[i]);
         catch (ParseException e) 
            e.printStackTrace();
        

        calendar = dateToCalendar(date);
        System.out.println(calendar.getTime());

        List<Calendar> dates = new ArrayList<>();
        dates.add(calendar);
        Calendar[] disabledDays1 = dates.toArray(new Calendar[dates.size()]);
        dpd.setDisabledDays(disabledDays1);
    

【讨论】:

【参考方案3】:

android datepicker 无法做到这一点,您需要为自己创建一个自定义选择器。见MaterialDateTimePicker

要禁用星期日,您必须像这样传递数组

      GregorianCalendar g1=new GregorianCalendar();
      g1.add(Calendar.DATE, 1);
      GregorianCalendar gc = new GregorianCalendar();
      gc.add(Calendar.DAY_OF_MONTH, 30);
       List<Calendar> dayslist= new LinkedList<Calendar>();
Calendar[] daysArray;
Calendar cAux = Calendar.getInstance();
while ( cAux.getTimeInMillis() <= gc.getTimeInMillis()) 
    if (cAux.get(Calendar.DAY_OF_WEEK) != 1) 
        Calendar c = Calendar.getInstance();
        c.setTimeInMillis(cAux.getTimeInMillis());
        dayslist.add(c);
    
    cAux.setTimeInMillis(cAux.getTimeInMillis() + (24*60*60*1000));

daysArray = new Calendar[dayslist.size()];
for (int i = 0; i<daysArray.length;i++)

    daysArray[i]=dayslist.get(i);

datePickerDialog.setSelectableDays(daysArray);

【讨论】:

使用 Calendar.SUNDAY 而不是 1【参考方案4】:

访问https://***.com/a/44692231/6631959 最好的方法和易于理解... 如果您正在寻找如何禁用指定日期,那就更好了。 不是循环程序。给出任何确切的日期并禁用它。

代码在这里::

SimpleDateFormat sdf = new SimpleDateFormat("dd-MM-yyyy");
                    String a = "26-07-2017";
                    java.util.Date date = null;
                    try 
                        date = sdf.parse(a);
                        MainActivity obj = new MainActivity();
                        calendar = obj.dateToCalendar(date);
                        System.out.println(calendar.getTime());
                     catch (ParseException e) 
                        e.printStackTrace();
                    

                    List<Calendar> dates = new ArrayList<>();
                    dates.add(calendar);
                    Calendar[] disabledDays1 = dates.toArray(new Calendar[dates.size()]);
                    dpd.setDisabledDays(disabledDays1);
    private Calendar dateToCalendar(Date date) 
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(date);
            return calendar;
        

【讨论】:

【参考方案5】:

由于这里接受的答案依赖于 com.wdullaer 的自定义实现,我想提出另一个我刚刚使用标准 MaterialDatePicker 和自定义 DateValidator 实现的解决方案:

            // Create a custom date validator to only enable dates that are in the list
        val customDateValidator = object: CalendarConstraints.DateValidator 
            override fun describeContents(): Int   return 0  
            override fun writeToParcel(dest: Parcel?, flags: Int)     
            override fun isValid(date: Long): Boolean 

                listOfPossibleDatesAsLong.forEach 
                    val itemDateTime = Calendar.getInstance()
                    itemDateTime.timeInMillis = it

                    val dateDateTime = Calendar.getInstance()
                    dateDateTime.timeInMillis = date

                    if(itemDateTime.get(Calendar.YEAR) == dateDateTime.get(Calendar.YEAR)
                        && itemDateTime.get(Calendar.MONTH) == dateDateTime.get(Calendar.MONTH)
                        && itemDateTime.get(Calendar.DAY_OF_MONTH) == dateDateTime.get(Calendar.DAY_OF_MONTH))
                        return true
                
                return false
            
        

除了 CalendarConstraints 中的其他约束,现在只需设置 customDateValidator,这也可以与 setStart(...) 和 setEnd(...) 一起使用

        // Build constraints.
        val constraintsBuilder =
            CalendarConstraints.Builder().apply 
                    // other constraints
                    setValidator(customDateValidator)
                
            

然后定义datePicker并显示出来

        val datePicker =
            MaterialDatePicker.Builder.datePicker()
                .setTitleText("Select date")
                .setSelection(MaterialDatePicker.todayInUtcMilliseconds())
                .setCalendarConstraints(constraintsBuilder.build())
                .build()

        datePicker.addOnPositiveButtonClickListener 
            // Respond to positive button click...
        

        datePicker.show(parentFragmentManager, "tag")

我需要承认,我不明白如果没有正确实施 describeContents 和 writeToParcel 是否会对任何事情产生负面影响,也许可以在这里讨论。但是,就我的目的而言,这非常有效。

【讨论】:

我在验证器中比较日期的方式在真实设备上不起作用,所以我更新了上面的代码。【参考方案6】:

试试Android Material Date and Timepicker

来源Link

周日和周六禁用。

您还可以使用 setDisabledDays() 方法禁用任何特定日期

            //Disable all SUNDAYS and SATURDAYS between Min and Max Dates
            for (Calendar loopdate = min_date_c; min_date_c.before(max_date_c); min_date_c.add(Calendar.DATE, 1), loopdate = min_date_c) 
                int dayOfWeek = loopdate.get(Calendar.DAY_OF_WEEK);
                if (dayOfWeek == Calendar.SUNDAY || dayOfWeek == Calendar.SATURDAY) 
                    Calendar[] disabledDays =  new Calendar[1];
                    disabledDays[0] = loopdate;
                    datePickerDialog.setDisabledDays(disabledDays);
                
            

【讨论】:

【参考方案7】:

使用MaterialDatePicker 中的https://github.com/material-components/material-components-android

在选择器中禁用周末的示例

val constraintsBuilder =
        CalendarConstraints.Builder().setValidator(DateValidatorWeekdays()).build()

    MaterialDatePicker.Builder.datePicker().setCalendarConstraints(constraintsBuilder).build()
        .show(childFragmentManager, "Data_Picker")

DateValidator 类:

https://github.com/material-components/material-components-android/blob/master/catalog/java/io/material/catalog/datepicker/DateValidatorWeekdays.java

【讨论】:

以上是关于在 Android 日期选择器中禁用特定日期的主要内容,如果未能解决你的问题,请参考以下文章

如何在蚂蚁设计日期选择器中禁用所有星期日和特定日期数组

如何在 jQuery 日期选择器中为禁用日期添加工具提示?

在引导日期选择器中启用特定日期

在引导日期时间选择器中禁用时间

从日期选择器中的特定日期计算每月的第一周?

如何在日期选择器中禁用自定义日期以及以前的日期?