Sha*_* GN 5 android android-layout android-fragments
我已经在我的 Android 应用程序中使用 Android 多产材料 CalendarView 外部库实现了 CalendarView。现在,我必须在某些日期下方添加多个点指示器,以指示每个日期中的事件数量。我尝试过,但只在日期下方得到一个点。请帮忙
这是我的日历片段和装饰器类:
public class CalendarFragment extends Fragment {
private View v;
private List<Schedule> schedules = new ArrayList<Schedule>( );
private MaterialCalendarView calendarView;
public CalendarFragment() {
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
try {
v = inflater.inflate(R.layout.fragment_calendar, container, false);
initViews();
schedules = ScheduleDAO.getInstance().getScheduleListWithId();
highlightDates(schedules);
} catch (ParseException e) {
e.printStackTrace();
}
return v;
}
private void highlightDates(List<Schedule>scheduleList) throws ParseException {
for (int position = 0;position<scheduleList.size();position++)
{
Schedule schedule = scheduleList.get(position);
if (schedule.getSessionStatus().equals("Incomplete")){
int color = R.color.colorPrimaryDark;
CurrentDayDecorator decorator = new CurrentDayDecorator(new Date(schedule.getScheduledDate()),color);
calendarView.addDecorator(decorator);
}else {
int color = R.color.lightgray;
CurrentDayDecorator decorator = new CurrentDayDecorator(new Date(schedule.getScheduledDate()),color);
calendarView.addDecorator(decorator);
}
}
}
private void initViews() {
calendarView = v.findViewById(R.id.calendarView);
}
}
Decorator class
public class CurrentDayDecorator implements DayViewDecorator {
private final int color;
private final CalendarDay day;
public CurrentDayDecorator(Date date,int color) {
this.color = color;
this.day = CalendarDay.from(date);
}
@Override
public boolean shouldDecorate(CalendarDay day) {
if (this.day.equals(day)){
return true;
}
return false;
}
@Override
public void decorate(DayViewFacade view) {
view.addSpan(new DotSpan(3,color));
}
}
Run Code Online (Sandbox Code Playgroud)
我遇到了类似的问题,发现这篇文章非常有帮助。
MaterialViewCalendar API 不支持您想要执行的操作,因此您需要添加一些额外的帮助程序类。请注意,一个装饰器映射到一个点。因此,如果您想要给定日期下有两个点,那么该日期必须绑定到两个装饰器等。
解决该问题的一种方法是执行以下操作:
decorate将类中的 -method更改CurrentDayDecorator为以下内容:
@Override
public void decorate(DayViewFacade view) {
LineBackgroundSpan span = new CustomSpan(color, xOffsets[spanType]);
view.addSpan(span);
}
Run Code Online (Sandbox Code Playgroud)
正如您所看到的,我们需要向您的类添加一个新类 ( CustomSpan) 和两个字段 (xOffsets和spanType) CurrentDayDecorator。LineBackgroundSpan 是包中包含的接口。
private static class CustomSpan extends DotSpan{
private int color;
private int xOffset;
private float radius = 3;
CustomSpan(int color, int xOffset){
this.color = color;
this.xOffset = xOffset;
}
/*Note! The following code is more or less copy-pasted from the DotSpan class. I have commented the changes below.*/
@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);
}
int x = ((left + right) / 2); /*This is the x-coordinate right
below the date. If we add to x, we will draw the
circle to the right of the date and vice versa if we subtract from x.*/
canvas.drawCircle(x + xOffset, bottom + radius, radius, paint);
paint.setColor(oldColor);
}
}
Run Code Online (Sandbox Code Playgroud)
所以剩下的就是向我们的 CustomSpan 提供一个偏移量。在我自己的装饰器方法中,我有一系列偏移量可供选择。我选择哪一个取决于我要创建哪个点。在我的应用程序中,我最多可以在日期下方放置 4 个点。CurrentDayDecorator在绘制之前,我需要告诉我它“代表”4 个点中的哪一个。
这就是我的类的样子(对于您来说,只需将“EventDecorator”更改为“CurrentDayDecorator”)
private static class EventDecorator implements DayViewDecorator {
private static final float DEFAULT_DOT_RADIUS = 4;
//Note that negative values indicate a relative offset to the LEFT
private static final int[] xOffsets = new int[]{0,-10,10,-20};
private int color;
private HashSet<CalendarDay> dates;
private float dotRadius;
private int spanType;
private EventDecorator(int color, float dotRadius, int spanType) {
this.color = color;
this.dotRadius = dotRadius;
this.dates = new HashSet<>();
this.spanType = spanType;
}
/*Note! I added this method so that I can add dates after object creation!*/
public boolean addDate(CalendarDay day){
return dates.add(day);
}
@Override
public boolean shouldDecorate(CalendarDay day) {
return dates.contains(day);
}
@Override
public void decorate(DayViewFacade view) {
LineBackgroundSpan span = new CustomSpan(color, xOffsets[spanType],DEFAULT_DOT_RADIUS);
view.addSpan(span);
}
}
Run Code Online (Sandbox Code Playgroud)
现在棘手的部分变成知道何时创建具有正确对应的 DayViewDecorator spanType。如果一天应该有两个点,那么它就需要两个DayViewDecorators(具有不同的值spanType)。我所做的是用“事件”来跟踪所有日子,并将每个“多事的日子”与一个计数器相关联。换句话说,aHashMap将 a 映射CalendarDay到 an Integer。然后,您遍历地图中的每个条目,并将给定的日期添加到 X 数量的装饰器中,其中 X 是事件的总数。在代码中它看起来像这样:
EventDecorator[] decoratorArray = new EventDecorator[4]; //Max 4 dots
for(int i = 0; i<decoratorArray.length; i++)
decoratorArray[i] = new EventDecorator(myColor,myRadius,i);
/*dayInstanceMap contains all the mappings.*/
for(Map.Entry<CalendarDay,Integer> entry : dayInstanceMap.entrySet()){
CalendarDay currDay = entry.getKey();
Integer currDayCount = entry.getValue(); //If you have max amount of dots, check here if currDay is too large.
for(int i = 0; i<currDayCount; i++)
decoratorArray[i].addDate(currDay);
}
Run Code Online (Sandbox Code Playgroud)
之后,只需将装饰器添加到 MaterialCalendarView 中即可。
| 归档时间: |
|
| 查看次数: |
5166 次 |
| 最近记录: |