Android Material CalendarView如何为不同日期分组设置对应装饰样式
问题原因
- 你复用了同一个
ArrayList实例存储不同分组的日期,创建黄色分组装饰器时,传入的集合已经包含了红色分组的2个日期,导致装饰范围错误 - 未对Drawable调用
mutate()方法,Android默认共享同一份Drawable资源的常量状态,多个装饰器修改tint时会互相覆盖
修复方案
1. MainActivity逻辑修改
不同分组使用独立的日期集合,代码如下:
// 红色分组:独立创建集合 ArrayList<CalendarDay> redDates = new ArrayList<>(); redDates.add(CalendarDay.from(2021, 8, 29)); // 注意:CalendarDay月份从0开始,8代表9月 redDates.add(CalendarDay.from(2021, 8, 30)); materialCalendarView.addDecorator(new mDayDecorator(Color.RED, redDates, MainActivity.this)); // 黄色分组:新建另一个集合,不要复用上面的集合 ArrayList<CalendarDay> yellowDates = new ArrayList<>(); yellowDates.add(CalendarDay.from(2021, 8, 1)); yellowDates.add(CalendarDay.from(2021, 8, 2)); yellowDates.add(CalendarDay.from(2021, 8, 3)); yellowDates.add(CalendarDay.from(2021, 8, 4)); yellowDates.add(CalendarDay.from(2021, 8, 5)); yellowDates.add(CalendarDay.from(2021, 8, 6)); materialCalendarView.addDecorator(new mDayDecorator(Color.YELLOW, yellowDates, MainActivity.this));
2. mDayDecorator修改
添加Drawable的mutate调用,避免状态共享:
public class mDayDecorator implements DayViewDecorator { private Drawable drawable; private int color; private HashSet<CalendarDay> dates = new HashSet<>(); @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP) public mDayDecorator(int color, Collection<CalendarDay> dates, Context context) { this.color = color; this.dates = new HashSet<>(dates); // 调用mutate() 避免多个装饰器共享Drawable状态 drawable = context.getDrawable(R.drawable.more).mutate(); } @Override public boolean shouldDecorate(CalendarDay day) { return dates.contains(day); } @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP) @Override public void decorate(DayViewFacade view) { drawable.setTint(color); view.setSelectionDrawable(drawable); } }
提示:如果同一个日期存在于多个分组的集合中,后添加的装饰器效果会覆盖先添加的,可根据业务需要调整装饰器的添加顺序。
效果示例

内容的提问来源于stack exchange,提问作者승현정
相关产品推荐
相关产品推荐

