在 MaterialCalendarView 中使用多个 DotSpan
Using multiple DotSpan's in MaterialCalendarView
有什么方法可以使用 Android MaterialCalendarView 将超过 1 个 DotSpan 附加到日期?
尽管我在我的 CalendarView 中添加了 2 个 DotSpan,但它仍然只显示 1 个 DotSpan ...
我正在使用以下代码:
@Override
public boolean shouldDecorate(CalendarDay day) {
day.copyTo(calendar);
for (int i = 0; i < weekDayStrTmp.size(); i++) {
if (weekDayStrTmp.contains(day)) {
return true;
} else {
return false;
}
}
return false;
}
@Override
public void decorate(DayViewFacade view) {
view.addSpan(new DotSpan(8, myContext.getResources().getColor(R.color.myColor3)));
view.addSpan(new DotSpan(8, myContext.getResources().getColor(R.color.myColor3)));
}
您正在用第二个覆盖第一个 DotSpan。
给定的 DotSpan class,可让您在文本下方创建一个居中的彩色点,因此如果您将一个点放在另一个之上,第一个点将不可见。
我已经设法在同一个 DayViewFacade 视图中创建了几个 DotSpans,我不确定这是否是您搜索的确切解决方案,但我相信它会有所帮助:
因此您必须创建一个自定义装饰器 class,它 实现 DayViewDecorator,我们称它为 OrangeDecorator。
您必须创建另一个自定义 class,它 实现 LineBackgroundSpan,我们将其称为 MyCustomOrangeSpan。
这两个 classes 与原始库中的原始 DotSpan 和 EventDecorator 几乎相同,但您可以根据需要自定义 classes。
在 "decorate" 函数 (OrangeDecorator class) 中使用您的自定义 LineBackgroundSpan,如下所示:
@Override
public void decorate(DayViewFacade view) {
view.addSpan(new MyCustomOrangeSpan(6, ContextCompat.getColor(mContext, R.color.AppOrange)));
}
在 "drawBackground" 函数 (MyCustomOrangeSpan class) 中,您可以将圆定位在 canvas 内,让我们开始吧:
@Override
public void drawBackground(Canvas canvas, Paint paint, int left, int right, int top, int baseline,
int bottom, CharSequence text, int start, int end, int lnum) {
int oldColor = paint.getColor();
if (color != 0) {
paint.setColor(color);
}
canvas.drawCircle((left + right) / 2 - 20, bottom + radius, radius, paint);
paint.setColor(oldColor);
}
这样,我们可以创建多个DayViewDecorators和LineBackgroundSpan(用于不同的定位):
BlueDecorator blueDecorator = new BlueDecorator(getActivity(),eventsDays,eventsMap);
OrangeDecorator orangeDecorator = new OrangeDecorator(getActivity(),eventsDays,eventsMap);
GreenDecorator greenDecorator = new GreenDecorator(getActivity(),eventsDays,eventsMap);
materialCalendarView.addDecorator(blueDecorator);
materialCalendarView.addDecorator(orangeDecorator);
materialCalendarView.addDecorator(greenDecorator);
我不得不想办法添加多个点,所选答案肯定帮助我解决了问题:
首先,您需要一个自定义的 DotSpan class,只需稍微改动一下即可:
public class CustmMultipleDotSpan implements LineBackgroundSpan {
private final float radius;
private int[] color = new int[0];
public CustmMultipleDotSpan() {
this.radius = DEFAULT_RADIUS;
this.color[0] = 0;
}
public CustmMultipleDotSpan(int color) {
this.radius = DEFAULT_RADIUS;
this.color[0] = 0;
}
public CustmMultipleDotSpan(float radius) {
this.radius = radius;
this.color[0] = 0;
}
public CustmMultipleDotSpan(float radius, int[] color) {
this.radius = radius;
this.color = color;
}
@Override
public void drawBackground(
Canvas canvas, Paint paint,
int left, int right, int top, int baseline, int bottom,
CharSequence charSequence,
int start, int end, int lineNum
) {
int total = color.length > 5 ? 5 : color.length;
int leftMost = (total - 1) * -10;
for (int i = 0; i < total; i++) {
int oldColor = paint.getColor();
if (color[i] != 0) {
paint.setColor(color[i]);
}
canvas.drawCircle((left + right) / 2 - leftMost, bottom + radius, radius, paint);
paint.setColor(oldColor);
leftMost = leftMost + 20;
}
}
}
您还需要一个稍作改动的 EventDecorator:
public class EventDecorator implements DayViewDecorator {
private final int[] colors;
private final HashSet<CalendarDay> dates;
public EventDecorator(Collection<CalendarDay> dates, int[] colors) {
//this.color = color;
this.dates = new HashSet<>(dates);
this.colors = colors;
}
public EventDecorator(List<MainActivity.Filter> filteredEvents) {
//this.color = color;
this.dates = new HashSet<>(filteredEvents.get(0).calDayArr);
int[] colors = new int[1];
colors[0] = filteredEvents.get(0).color;
this.colors = colors;
}
@Override
public boolean shouldDecorate(CalendarDay day) {
return dates.contains(day);
}
@Override
public void decorate(DayViewFacade view) {
view.addSpan((new CustmMultipleDotSpan(5,colors)));
}
}
基本上就是这样。
现在在您的 activity 中找到您的日历视图,并为其提供一些日期和颜色以在这些日期显示。在我的特殊情况下,我根据每天的事件数量将我的日期排序在 5 个不同的列表中,所以你最终会得到类似
的结果
calendarView.addDecorator(new EventDecorator(threeEventDays,threeColors));
其中 threeEventDays 是 CalendarDay 的集合
threeColors 是一个 int 数组
int[] threeColors = {
Color.rgb(0, 0, 255),
Color.rgb(0, 255, 0),
Color.rgb(255, 0, 0)};
它远没有达到应有的理想状态,但它的作用是需要一系列颜色。根据数组大小计算最左边的位置,因此对于一个大小的数组,最左边的位置是我们都知道和喜爱的中间点。对于尺寸 2,最左边的位置是 -10,对于尺寸 3,它是 -20 等等。然后循环并绘制点。
它仅限于 5 个事件点,因为它在上面变得非常丑陋,虽然目前不在我的路线图上,但如果事实证明这是一个要求,我可能会添加对第二行点的支持。
有什么方法可以使用 Android MaterialCalendarView 将超过 1 个 DotSpan 附加到日期? 尽管我在我的 CalendarView 中添加了 2 个 DotSpan,但它仍然只显示 1 个 DotSpan ... 我正在使用以下代码:
@Override
public boolean shouldDecorate(CalendarDay day) {
day.copyTo(calendar);
for (int i = 0; i < weekDayStrTmp.size(); i++) {
if (weekDayStrTmp.contains(day)) {
return true;
} else {
return false;
}
}
return false;
}
@Override
public void decorate(DayViewFacade view) {
view.addSpan(new DotSpan(8, myContext.getResources().getColor(R.color.myColor3)));
view.addSpan(new DotSpan(8, myContext.getResources().getColor(R.color.myColor3)));
}
您正在用第二个覆盖第一个 DotSpan。 给定的 DotSpan class,可让您在文本下方创建一个居中的彩色点,因此如果您将一个点放在另一个之上,第一个点将不可见。
我已经设法在同一个 DayViewFacade 视图中创建了几个 DotSpans,我不确定这是否是您搜索的确切解决方案,但我相信它会有所帮助:
因此您必须创建一个自定义装饰器 class,它 实现 DayViewDecorator,我们称它为 OrangeDecorator。
您必须创建另一个自定义 class,它 实现 LineBackgroundSpan,我们将其称为 MyCustomOrangeSpan。
这两个 classes 与原始库中的原始 DotSpan 和 EventDecorator 几乎相同,但您可以根据需要自定义 classes。
在 "decorate" 函数 (OrangeDecorator class) 中使用您的自定义 LineBackgroundSpan,如下所示:
@Override
public void decorate(DayViewFacade view) {
view.addSpan(new MyCustomOrangeSpan(6, ContextCompat.getColor(mContext, R.color.AppOrange)));
}
在 "drawBackground" 函数 (MyCustomOrangeSpan class) 中,您可以将圆定位在 canvas 内,让我们开始吧:
@Override
public void drawBackground(Canvas canvas, Paint paint, int left, int right, int top, int baseline,
int bottom, CharSequence text, int start, int end, int lnum) {
int oldColor = paint.getColor();
if (color != 0) {
paint.setColor(color);
}
canvas.drawCircle((left + right) / 2 - 20, bottom + radius, radius, paint);
paint.setColor(oldColor);
}
这样,我们可以创建多个DayViewDecorators和LineBackgroundSpan(用于不同的定位):
BlueDecorator blueDecorator = new BlueDecorator(getActivity(),eventsDays,eventsMap);
OrangeDecorator orangeDecorator = new OrangeDecorator(getActivity(),eventsDays,eventsMap);
GreenDecorator greenDecorator = new GreenDecorator(getActivity(),eventsDays,eventsMap);
materialCalendarView.addDecorator(blueDecorator);
materialCalendarView.addDecorator(orangeDecorator);
materialCalendarView.addDecorator(greenDecorator);
我不得不想办法添加多个点,所选答案肯定帮助我解决了问题:
首先,您需要一个自定义的 DotSpan class,只需稍微改动一下即可:
public class CustmMultipleDotSpan implements LineBackgroundSpan {
private final float radius;
private int[] color = new int[0];
public CustmMultipleDotSpan() {
this.radius = DEFAULT_RADIUS;
this.color[0] = 0;
}
public CustmMultipleDotSpan(int color) {
this.radius = DEFAULT_RADIUS;
this.color[0] = 0;
}
public CustmMultipleDotSpan(float radius) {
this.radius = radius;
this.color[0] = 0;
}
public CustmMultipleDotSpan(float radius, int[] color) {
this.radius = radius;
this.color = color;
}
@Override
public void drawBackground(
Canvas canvas, Paint paint,
int left, int right, int top, int baseline, int bottom,
CharSequence charSequence,
int start, int end, int lineNum
) {
int total = color.length > 5 ? 5 : color.length;
int leftMost = (total - 1) * -10;
for (int i = 0; i < total; i++) {
int oldColor = paint.getColor();
if (color[i] != 0) {
paint.setColor(color[i]);
}
canvas.drawCircle((left + right) / 2 - leftMost, bottom + radius, radius, paint);
paint.setColor(oldColor);
leftMost = leftMost + 20;
}
}
}
您还需要一个稍作改动的 EventDecorator:
public class EventDecorator implements DayViewDecorator {
private final int[] colors;
private final HashSet<CalendarDay> dates;
public EventDecorator(Collection<CalendarDay> dates, int[] colors) {
//this.color = color;
this.dates = new HashSet<>(dates);
this.colors = colors;
}
public EventDecorator(List<MainActivity.Filter> filteredEvents) {
//this.color = color;
this.dates = new HashSet<>(filteredEvents.get(0).calDayArr);
int[] colors = new int[1];
colors[0] = filteredEvents.get(0).color;
this.colors = colors;
}
@Override
public boolean shouldDecorate(CalendarDay day) {
return dates.contains(day);
}
@Override
public void decorate(DayViewFacade view) {
view.addSpan((new CustmMultipleDotSpan(5,colors)));
}
}
基本上就是这样。
现在在您的 activity 中找到您的日历视图,并为其提供一些日期和颜色以在这些日期显示。在我的特殊情况下,我根据每天的事件数量将我的日期排序在 5 个不同的列表中,所以你最终会得到类似
的结果calendarView.addDecorator(new EventDecorator(threeEventDays,threeColors));
其中 threeEventDays 是 CalendarDay 的集合 threeColors 是一个 int 数组
int[] threeColors = {
Color.rgb(0, 0, 255),
Color.rgb(0, 255, 0),
Color.rgb(255, 0, 0)};
它远没有达到应有的理想状态,但它的作用是需要一系列颜色。根据数组大小计算最左边的位置,因此对于一个大小的数组,最左边的位置是我们都知道和喜爱的中间点。对于尺寸 2,最左边的位置是 -10,对于尺寸 3,它是 -20 等等。然后循环并绘制点。
它仅限于 5 个事件点,因为它在上面变得非常丑陋,虽然目前不在我的路线图上,但如果事实证明这是一个要求,我可能会添加对第二行点的支持。