Ravi
Ravi

Reputation: 63

How to disable Dates in Android Material Calender

I'm using Material CalendarView and based array of dates CalenderView highlighting dates. So I want to disable the dates except Array of Dates.

 datePickerDialog = new Dialog(MainActivity.getInstance());
                    datePickerDialog.show();
                    datePickerDialog.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
                    datePickerDialog.getWindow().setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
                    datePickerDialog.setCancelable(true);
                    datePickerDialog.getWindow().setBackgroundDrawableResource(android.R.color.transparent);
                    datePickerDialog.setContentView(R.layout.assignment_custom_datepicker);
                    materialCalendarView = (MaterialCalendarView) datePickerDialog.findViewById(R.id.calendarView);
                  //  materialCalendarView.setShowOtherDates(MaterialCalendarView.SHOW_ALL);
                    materialCalendarView.setFirstDayOfWeek(Calendar.SUNDAY);
                    materialCalendarView.invalidate();

                    materialCalendarView.setHeaderTextAppearance(R.style.TextAppearance_AppCompat_Medium);
                    materialCalendarView.setDateTextAppearance(R.drawable.background_solid_blue);
                    materialCalendarView.setDateTextAppearance(R.style.TextAppearance_AppCompat_Medium);
                    materialCalendarView.setWeekDayTextAppearance(R.style.TextAppearance_AppCompat_Medium);
                    materialCalendarView.setSelectionMode(MaterialCalendarView.SELECTION_MODE_SINGLE);

                  //  materialCalendarView.setWeekDayTextAppearance();
                    materialCalendarView.setDateTextAppearance(R.style.WalletFragmentDefaultButtonTextAppearance);
                    Calendar selectDayCalendar = Calendar.getInstance();
                    selectDayCalendar.set(mYear, mMonth, mDay);
                    materialCalendarView.addDecorators(
                            new OneDayDecorator()
                    );
                    if (calendarDays != null && !calendarDays.isEmpty() ) {
                        materialCalendarView.addDecorator(new EventDecorator(Color.RED, calendarDays));
                        materialCalendarView.setOnDateChangedListener(this);


                    }
                    else
                    {
                        // materialCalendarView.setOnDateChangedListener(this);
                    }
                    if (readcalendarDays != null && !readcalendarDays.isEmpty()) {
                        materialCalendarView.addDecorator(new EventDecorator(Color.GREEN, readcalendarDays));

                    }

Upvotes: 2

Views: 8271

Answers (2)

Because for now, answer that provided by Ankur Aggarwal is not working - here is my solution.

Accepted answer will not work, because by default in MaterialCalendarView all days in enabled state.

First of all, we must disable all dates in MaterialCalendarView.

public class AllDaysDisabledDecorator implements DayViewDecorator {

        @Override
        public boolean shouldDecorate(CalendarDay day) {
            return true; //decorate all days in calendar
        }

        @Override
        public void decorate(DayViewFacade view) {
            view.setDaysDisabled(true); //disable all days
        }
   }

And add this decorator to MaterialCalendarView:

materialCalendarView.addDecorator(new AllDaysDisabledDecorator());

After that, we must add another decorator, but for available and enabled dates (like in accepted answer):

public class AvailableDaysDecorator implements DayViewDecorator {

        private final int color;
        private final HashSet<CalendarDay> dates;

        AvailableDaysDecorator(int color, Collection<CalendarDay> dates) {
            this.color = color;
            this.dates = new HashSet<>(dates);
        }

        @Override
        public boolean shouldDecorate(CalendarDay day) {
            return dates.contains(day); //decorate only available days
        }

        @Override
        public void decorate(DayViewFacade view) {
            view.setDaysDisabled(false); ///important to enable day
            view.addSpan(new DotSpan(5, color)); //adds small dot to bottom of day number text
        }
    }

And add this second decorator:

materialCalendarView.addDecorator(new AvailableDaysDecorator(R.color.colorPrimary, days));

So, after this simple actions, you will get only needed days enabled and disabled all another days.

Upvotes: 3

Ankur Aggarwal
Ankur Aggarwal

Reputation: 2220

Try the following :

ArrayList<CalendarDay> enabledDates = new ArrayList<>();

//Some for loop on dates{
    enabledDates.add(new CalendarDay(date));
}

materialCalendarView.addDecorator(calendarDecorator.new DayEnableDecorator(enabledDates));

The DayEnableDecorator is a separate class:

public class DayEnableDecorator implements DayViewDecorator{
    private HashSet<CalendarDay> dates;

    public DayEnableDecorator(Collection<CalendarDay> dates) {
        this.dates = new HashSet<>(dates);
    }

    @Override
    public boolean shouldDecorate(CalendarDay day) {
        return dates.contains(day);
    }

    @Override
    public void decorate(DayViewFacade view) {
        view.setDaysDisabled(false);
    }
}

This would enable the dates that you put in the array enabledDates and disable the rest

Upvotes: 3

Related Questions