Labelling material-calendarview with Events

100 Views Asked by At

I'm trying to use prolificinteractive's material-calendarview to achieve something similar to the image I've attached, which has events added to the calendar. I'm thinking I could do this by creating a custom Span class as shown here in another post.

However, my issue is that DayViewDecorator.decorate doesn't know which date it's currently decorating, so I can't pass specific event names to it. Is there a way I could achieve this using material-calendarview or are there other alternatives? Cheers

What I'm trying to achieve

MainActivity.kt I thought decorate would be called after shouldDecorate, so I could define calendarDay in shouldDecorate, then call for its corresponding Event value in mapOfCalendarDays. But decorate is actually called first, and only once, before shouldDecorate is called for each day in the Calendar. This results in a crash, though, since calendarDay has not yet been initialized.

calendarView.addDecorator(object: DayViewDecorator {
    lateinit var calendarDay: CalendarDay

    override fun shouldDecorate(day: CalendarDay?): Boolean {
        return if (mapOfCalendarDays.containsKey(day)) { // check if 'day' is in mapOfCalendarDays (a map of CalendarDay to Event)
            calendarDay = day!!
            true
        } else false
    }

    override fun decorate(view: DayViewFacade?) {
        val event: Event? = mapOfCalendarDays[calendarDay]
        if (event != null) {
            view?.addSpan(AddTextToDates(event.name))
        }
    }
})

Event.kt

data class Event(
    val name: String,
    val date: LocalDate
)

AddTextToDates.kt

class AddTextToDates(text: String): LineBackgroundSpan {

    private val eventName = text

    override fun drawBackground(
        canvas: Canvas,
        paint: Paint,
        left: Int,
        right: Int,
        top: Int,
        baseline: Int,
        bottom: Int,
        text: CharSequence,
        start: Int,
        end: Int,
        lnum: Int
    ) {
        canvas.drawText(eventName, ((left+right)/4).toFloat(), (bottom+15).toFloat(), paint)
    }
}
0

There are 0 best solutions below