Using multiple DotSpan's in MaterialCalendarView

后端 未结 2 1649
清酒与你
清酒与你 2021-02-04 16:15

Is there any way of attaching more than 1 DotSpan\'s to a date with Android MaterialCalendarView? Altough I have 2 DotSpan\'s added to my CalendarView it\'s still displaying onl

相关标签:
2条回答
  • 2021-02-04 16:35

    I had to figure a way to add multiple dots, the selected answer definitely helped me figure things out:

    First off, you need a custom DotSpan class, which is just ever so slightly altered:

    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;
            }
        }
    }
    

    You will also need an ever so slightly altered 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)));
    
        }
    
    
    }
    

    And that is basically it.

    Now find your calendarview in your activity, and give it some dates, and colors to show on those dates. In my particular case, I sort my dates in 5 different lists based on the amount of events per day, so you will end up with something like

    calendarView.addDecorator(new EventDecorator(threeEventDays,threeColors));
    

    Where threeEventDays is a Collection of CalendarDay and threeColors is an int array

    int[] threeColors = {
    Color.rgb(0, 0, 255),
    Color.rgb(0, 255, 0),
    Color.rgb(255, 0, 0)};
    

    It's nowhere near as ideal as it should be, but what it does is it expects an array of colors. Calculates the leftmost position, based on the array size, so for a size one, the left most position is the middle dot we all know and love. For size 2 the left most position is -10, for size 3 it's -20 and so on. Then loops through and paints the dots.

    It's limited to 5 event dots as it gets quite ugly above that, and though currently not on my roadmap, if it turns out to be a requirement I might add support for a second line of dots.

    0 讨论(0)
  • 2021-02-04 16:40

    You are overriding the first DotSpan with the second. The given DotSpan class, lets you create a centered colored dot below the text, so if you put one on top of the other, the first won't be visible.

    I've managed to create few DotSpans at the same DayViewFacade view, I'm not sure if that's the exact solution you searched for but I'm sure it'll be helpful:

    So you have to create a custom Decorator class that implements DayViewDecorator, let's call it OrangeDecorator.

    You'll have to create another custom class that implements LineBackgroundSpan, and we'll call it MyCustomOrangeSpan.

    Both classes are almost the same as the original DotSpan and EventDecorator taken from the original library, but you can customize the classes for your needs.

    At the "decorate" function (OrangeDecorator class) use your custom LineBackgroundSpan like so:

    @Override
    public void decorate(DayViewFacade view) {
        view.addSpan(new MyCustomOrangeSpan(6, ContextCompat.getColor(mContext, R.color.AppOrange)));
    }
    

    At the "drawBackground" function (MyCustomOrangeSpan class) you'll be able to position the circle inside the canvas, so let's do it:

    @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);
    
        }
    

    This way, we can create multiple DayViewDecorators and LineBackgroundSpan (for different positioning):

    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);
    
    0 讨论(0)
提交回复
热议问题