Skip to content Skip to sidebar Skip to footer

Using Multiple Dotspan's In Materialcalendarview

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 only 1 Do

Solution 1:

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:

@Overridepublicvoiddecorate(DayViewFacade view) {
    view.addSpan(newMyCustomOrangeSpan(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:

@OverridepublicvoiddrawBackground(Canvas canvas, Paint paint, int left, int right, int top, int baseline,
                               int bottom, CharSequence text, int start, int end, int lnum) {

        intoldColor= 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):

BlueDecoratorblueDecorator=newBlueDecorator(getActivity(),eventsDays,eventsMap);
OrangeDecoratororangeDecorator=newOrangeDecorator(getActivity(),eventsDays,eventsMap);
GreenDecoratorgreenDecorator=newGreenDecorator(getActivity(),eventsDays,eventsMap);
materialCalendarView.addDecorator(blueDecorator);
materialCalendarView.addDecorator(orangeDecorator);
materialCalendarView.addDecorator(greenDecorator);

Solution 2:

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:

publicclassCustmMultipleDotSpanimplementsLineBackgroundSpan {


    privatefinalfloat radius;
    privateint[] color = newint[0];


    publicCustmMultipleDotSpan() {
        this.radius = DEFAULT_RADIUS;
        this.color[0] = 0;
    }


    publicCustmMultipleDotSpan(int color) {
        this.radius = DEFAULT_RADIUS;
        this.color[0] = 0;
    }


    publicCustmMultipleDotSpan(float radius) {
        this.radius = radius;
        this.color[0] = 0;
    }


    publicCustmMultipleDotSpan(float radius, int[] color) {
        this.radius = radius;
        this.color = color;
    }

    @OverridepublicvoiddrawBackground(
            Canvas canvas, Paint paint,
            int left, int right, int top, int baseline, int bottom,
            CharSequence charSequence,
            int start, int end, int lineNum
    ) {

        inttotal= color.length > 5 ? 5 : color.length;
        intleftMost= (total - 1) * -10;

        for (inti=0; i < total; i++) {
            intoldColor= 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:

publicclassEventDecoratorimplementsDayViewDecorator {

    privatefinalint[] colors;
    privatefinal HashSet<CalendarDay> dates;


    publicEventDecorator(Collection<CalendarDay> dates, int[] colors) {
        //this.color = color;this.dates = newHashSet<>(dates);

        this.colors = colors;

    }


    publicEventDecorator(List<MainActivity.Filter> filteredEvents) {
        //this.color = color;this.dates = newHashSet<>(filteredEvents.get(0).calDayArr);
        int[] colors = newint[1];
        colors[0] = filteredEvents.get(0).color;
        this.colors = colors;

    }

    @OverridepublicbooleanshouldDecorate(CalendarDay day) {
        return dates.contains(day);
    }

    @Overridepublicvoiddecorate(DayViewFacade view) {

        view.addSpan((newCustmMultipleDotSpan(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(newEventDecorator(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.

Post a Comment for "Using Multiple Dotspan's In Materialcalendarview"