我的目标是找到一个Android库,允许我根据数组在日历视图上标记各种日期。日期可能是也可能不是连续的。我理想的情况是改变每个日期的背景颜色。重要的复杂因素是我在运行时之前不知道这种颜色,因为它将来自服务器查询。
我整天都在研究这个问题,我最大的希望似乎是material-calendarview
(github)。但是,我发现他们的代码有点难以理解,这在我身上,但我完全陷入困境。
我在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"/>
然后在我的活动中,我有这些实例变量:
private MaterialCalendarView calendarView;
private ArrayList<Date> markedDates;
和我的onCreateView()
calendarView = (MaterialCalendarView) view.findViewById(R.id.calendar_view);
好的,够容易的。但我无法弄清楚如何从我的日期数组中标记日历。我正在研究这种方法,但我不知道如何超越我的方法:
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, ????));
}
最后一行引用了这个内部类:
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));
}
}
我认为将我的ArrayList<Date> markedDates
转换为他们所谓的Collection<CalendarDay> dates
我的挑战。同意?但这是我真正陷入困境的地方。这data structure对我来说很奇怪。当我尝试通过调用new CalendarDay()
来实例化它时,我的班级立即扩展了大约10种新方法,我不了解他们的角色或者如何处理它们。很明显,我要离开这里了。它不会那么棘手。
是否有人为此目的使用此库并知道如何完成此任务?我停下来了。此外,如果有一个更简单的库允许我使用仅在运行时知道的颜色设置背景颜色,我全都是耳朵。
感谢您的帮助。我担心我是以一种令人困惑的方式写出来的,这是因为我完全糊涂了这一事实。
答案 0 :(得分:4)
如果要以编程方式更改所选的背景颜色,请使用以下方法: -
MaterialCalendarView materialCalendar = (MaterialCalendarView)findViewById(R.id.materialCalenderView);
materialCalendar.setSelectionColor(Color.parseColor("#00BCD4"));
使用此代码会使所有选择器颜色相同,因此如果您想根据条件使用不同的颜色选择器,请使用装饰器()
答案 1 :(得分:3)
我解决了这个问题,所以我会发布该解决方案以防其他人有同样的问题。如果有更有效的方式,请发布解决方案。
我提到我有一个包含日期列表的数组。我需要做的是迭代该数组,将每个Date
转换为设置为适当的年,月和日的Calendar
对象,然后将该对象添加到另一个{{1} },这次是ArrayList
。例如:
ArrayList<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);
}
个CalendarDay
个对象的列表,但我们并不完全相同。创建数据结构的最后一步是转换&#39;这就是我提到的我在OP中挣扎的一个Collection<CalendarDay>
结构。事实证明,一旦我们到达这里,这一点就不会变得更简单了。只需像这样分配:
calendarDays = list;
然后当你想添加装饰器时,你就完成了所有设置。就这样做:
calendarView.addDecorators(new EventDecorator(myColor, calendarDays));
还有一件事需要提及,这是我困惑的主要原因。我不明白如何实例化这个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;
}
};
我希望这有助于某人。同样,如果有更好的解决方案,请发帖,我会删除我的。
答案 2 :(得分:2)
为什么使用ArrayList而不是HashSet? 您无法实例化Collection的原因是因为它是一个接口,因此您必须创建匿名类并覆盖这些方法。
以下是我做类似的事情:
此方法接受两个Calendar对象,并将两个Calendar日期之间的所有日期添加到CalendarDays的HashSet中。
getCurrentLocationSync()
在onCreateView(...)方法中,我已经动态设置了两个日历日期,它们之间的差异将存储在HashSet中。但是,您可以在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;
}
在我的情况下,BookingDecorator是实现DayViewDecorator接口的类。
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));
您的帖子非常有帮助。希望我的帮助也有人。