java material-calendarview 设置日期的背景颜色

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/33512727/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-02 21:47:19  来源:igfitidea点击:

material-calendarview set background color of dates

javaandroidcalendar

提问by AndroidDev

My goal is to find an Android library that will allow me to mark various dates on a calendar view based on an array. The dates may or may not be contiguous. My ideal scenario is to change the background color of each date. The significant complication is that I don't know this color until runtime, since it will come from a server query.

我的目标是找到一个 Android 库,它允许我基于数组在日历视图上标记各种日期。日期可能连续也可能不连续。我的理想场景是更改每个日期的背景颜色。重要的复杂性是我直到运行时才知道这种颜色,因为它来自服务器查询。

I've been researching this all day, and my best hope seems to be material-calendarview(github). However, I am finding their code to be somewhat impenetrable, which is on me, but I am completely stuck.

我一整天都在研究这个,我最大的希望似乎是material-calendarviewgithub)。但是,我发现他们的代码有些难以理解,这在我身上,但我完全被卡住了。

I've added a calendar like this in my XML layout:

我在 XML 布局中添加了这样的日历:

<com.prolificinteractive.materialcalendarview.MaterialCalendarView
        android:id="@+id/calendar_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_marginLeft="20dp"
        android:layout_marginRight="20dp"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        app:mcv_showOtherDates="all"
        app:mcv_selectionColor="#00F"/>

And then in my activity, I have these instance variables:

然后在我的活动中,我有这些实例变量:

private MaterialCalendarView calendarView;
private ArrayList<Date> markedDates;

and this code in my onCreateView()

这个代码在我的 onCreateView()

calendarView = (MaterialCalendarView) view.findViewById(R.id.calendar_view);

Ok, easy enough. But I cannot figure out how to mark the calendar from my array of dates. I am working on this method, but I just don't know how to proceed beyond what I have here:

好吧,很简单。但我无法弄清楚如何从我的日期数组中标记日历。我正在研究这种方法,但我只是不知道如何超越我在这里的方法:

private void initializeCalendar() {

        calendarView.setOnDateChangedListener(context);
        calendarView.setShowOtherDates(MaterialCalendarView.SHOW_ALL);

        Calendar calendar = Calendar.getInstance();
        calendarView.setSelectedDate(calendar.getTime());

        calendar.set(calendar.get(Calendar.YEAR), Calendar.JANUARY, 1);
        calendarView.setMinimumDate(calendar.getTime());

        calendar.set(calendar.get(Calendar.YEAR), Calendar.DECEMBER, 31);
        calendarView.setMaximumDate(calendar.getTime());

        int bgColor = sharedVisualElements.getPrimaryColor();

        calendarView.addDecorators(new EventDecorator(bgColor, ????));
}

That last line refers to this inner class:

最后一行指的是这个内部类:

private class EventDecorator implements DayViewDecorator {

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

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

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

        @Override
        public void decorate(DayViewFacade view) {
            view.addSpan(new DotSpan(5, color));
        }
    }

I think that my challenge to convert my ArrayList<Date> markedDatesto what they call Collection<CalendarDay> dates. Agree? But this is where I really bog down. This data structureis bizarre to me. When I try to instantiate it by calling new CalendarDay()my class immediately expands with about 10 new methods that I don't understand their role or what to do with them. Clearly, I am going off the rails here. It just can't be this tricky.

我认为我的挑战是将我的转换ArrayList<Date> markedDates为他们所说的Collection<CalendarDay> dates. 同意?但这是我真正陷入困境的地方。这种数据结构对我来说很奇怪。当我尝试通过调用new CalendarDay()我的类来实例化它时,我立即扩展了大约 10 个我不了解它们的作用或如何处理它们的新方法。显然,我在这里出轨了。不可能这么棘手。

Has anyone used this library for this purpose and know how to accomplish this task? I'm at a grinding halt. Also, if there is a simpler library to allow me to set background colors using a color only known at run-time, I'm all ears.

有没有人为此目的使用过这个库并且知道如何完成这个任务?我正处于停滞状态。此外,如果有一个更简单的库允许我使用仅在运行时已知的颜色设置背景颜色,我会全力以赴。

Thanks for any help. I fear that I have written this in a confusing manner, which is a result of the fact that I am completely confused.

谢谢你的帮助。我担心我写的很混乱,这是我完全糊涂的结果。

回答by AndroidDev

I solved this, so I'll post that solution in case anyone else has the same question. If there is a more efficient way, please post as a solution.

我解决了这个问题,所以我会发布该解决方案,以防其他人有同样的问题。如果有更有效的方法,请作为解决方案发布。

I mentioned that I have an array with a list of dates. What I need to do is to iterate over that array, converting each Dateinto a Calendarobject set to the appropriate year, month, and day, and then adding that object to a different ArrayList, this time an ArrayList<CalendarDay>. For example:

我提到我有一个包含日期列表的数组。我需要做的是遍历该数组,将每个对象转换DateCalendar设置为适当年、月和日的对象,然后将该对象添加到不同ArrayListArrayList<CalendarDay>. 例如:

List<CalendarDay> list = new ArrayList<CalendarDay>();
Calendar calendar = Calendar.getInstance();

for (Date date : markedDates) {
    // might be a more elegant way to do this part, but this is very explicit
    int year = date.getYear();
    int month = date.getMonthOfYear() - 1; // months are 0-based in Calendar
    int day = date.getDayOfMonth();

    calendar.set(year, month, day);
    CalendarDay calendarDay = CalendarDay.from(calendar);
    list.add(calendarDay);
}

So now we've got this list of CalendarDayobjects, but we're not quite there. The final step in creating the data structure is to 'convert' this over to what I mentioned I was struggling with in the OP - a Collection<CalendarDay>structure. Turns out this couldn't be any simpler once we get here. Simply assign it like this:

所以现在我们已经得到了这个CalendarDay对象列表,但我们还没有完全到位。创建数据结构的最后一步是将其“转换”为我提到的我在 OP 中遇到的问题 - 一个Collection<CalendarDay>结构。事实证明,一旦我们到达这里,事情就再简单不过了。只需像这样分配它:

calendarDays = list;

And then when you want to add the decorator, you're all set up. Just do this:

然后当你想添加装饰器时,一切都准备好了。只需这样做:

calendarView.addDecorators(new EventDecorator(myColor, calendarDays));

One other thing bears mentioning, and this was a major source of my confusion. I didn't understand how to instantiate this Collection<CalendarDay>object. Way up in the instance variable section (before the constructor), I added this code, almost all of which Android Studio filled in for me:

另一件事值得一提,这是我困惑的主要来源。我不明白如何实例化这个Collection<CalendarDay>对象。在实例变量部分(在构造函数之前),我添加了以下代码,Android Studio 几乎为我填写了所有代码:

private Collection<CalendarDay> calendarDays = new Collection<CalendarDay>() {
        @Override
        public boolean add(CalendarDay object) {
            return false;
        }

        @Override
        public boolean addAll(Collection<? extends CalendarDay> collection) {
            return false;
        }

        @Override
        public void clear() {

        }

        @Override
        public boolean contains(Object object) {
            return false;
        }

        @Override
        public boolean containsAll(Collection<?> collection) {
            return false;
        }

        @Override
        public boolean isEmpty() {
            return false;
        }

        @NonNull
        @Override
        public Iterator<CalendarDay> iterator() {
            return null;
        }

        @Override
        public boolean remove(Object object) {
            return false;
        }

        @Override
        public boolean removeAll(Collection<?> collection) {
            return false;
        }

        @Override
        public boolean retainAll(Collection<?> collection) {
            return false;
        }

        @Override
        public int size() {
            return 0;
        }

        @NonNull
        @Override
        public Object[] toArray() {
            return new Object[0];
        }

        @NonNull
        @Override
        public <T> T[] toArray(T[] array) {
            return null;
        }
    };

I hope that this helps someone. Again, if there is a better solution, please post and I'll delete mine.

我希望这对某人有所帮助。同样,如果有更好的解决方案,请发布,我将删除我的。

回答by Mrinmoy

If you want to change the background color of the selected programatically, use this method:-

如果要以编程方式更改所选背景颜色,请使用此方法:-

MaterialCalendarView materialCalendar = (MaterialCalendarView)findViewById(R.id.materialCalenderView);
materialCalendar.setSelectionColor(Color.parseColor("#00BCD4"));

Using this code makes all selectors of same color, so if you want to have different color selectors depending on your condition, use decorator()

使用此代码使所有选择器具有相同的颜色,因此如果您想根据条件使用不同的颜色选择器,请使用decorator()

回答by Sameer Khanal

Why did you use the ArrayList instead of the HashSet ? The reason you cannot instantiate Collection is because it is an interface, hence you had to create anonymous class and override the methods.

为什么使用 ArrayList 而不是 HashSet ?您不能实例化 Collection 的原因是因为它是一个接口,因此您必须创建匿名类并覆盖方法。

Here is how I did something similar:

这是我如何做类似的事情:

This method takes in two Calendar objects and adds all the days in between the two Calendar dates into a HashSet of CalendarDays.

此方法接收两个 Calendar 对象,并将两个 Calendar 日期之间的所有天数添加到 CalendarDays 的 HashSet 中。

private HashSet<CalendarDay> getCalendarDaysSet(Calendar cal1, Calendar cal2) {
    HashSet<CalendarDay> setDays = new HashSet<>();
    while (cal1.getTime().before(cal2.getTime())) {
        CalendarDay calDay = CalendarDay.from(cal1);
        setDays.add(calDay);
        cal1.add(Calendar.DATE, 1);
    }

    return setDays;
}

on the onCreateView(...) method,I have dynamically set the two calendar dates, the difference between which will be stored in the HashSet. However, you can pass your own random set of dates in the HashSet.

在 onCreateView(...) 方法上,我动态设置了两个日历日期,它们之间的差异将存储在 HashSet 中。但是,您可以在 HashSet 中传递您自己的随机日期集。

Calendar cal1 = Calendar.getInstance();
    cal1.set(2016, 8, 1);
    Calendar cal2 = Calendar.getInstance();
    cal2.set(2016, 9, 1);

    HashSet<CalendarDay> setDays = getCalendarDaysSet(cal1, cal2);
    int myColor = R.color.red;
    mCalendarView.addDecorator(new BookingDecorator(myColor, setDays));

In my case BookingDecorator is the class that implements the DayViewDecorator interface.

在我的例子中 BookingDecorator 是实现 DayViewDecorator 接口的类。

 private class BookingDecorator implements DayViewDecorator {
    private int mColor;
    private HashSet<CalendarDay> mCalendarDayCollection;

    public BookingDecorator(int color, HashSet<CalendarDay> calendarDayCollection) {
        mColor = color;
        mCalendarDayCollection = calendarDayCollection;
    }

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

    @Override
    public void decorate(DayViewFacade view) {
        view.addSpan(new ForegroundColorSpan(mColor));
        //view.addSpan(new BackgroundColorSpan(Color.BLUE));
        view.setBackgroundDrawable(ContextCompat.getDrawable(getContext(),R.drawable.greenbox));

    }
}

Your post was very helpful. Hope mine helps somebody as well.

你的帖子很有帮助。希望我的也能帮助别人。