Material-calendarview: How to get date in decorate(DayViewFacade view)

Created on 15 Apr 2016  路  18Comments  路  Source: prolificinteractive/material-calendarview

I'm going to develop lunar calendar.
I use decorate(DayViewFacade view) to set string in day view. But i can't find the way to get day of date view.
Please help me.
Tks you.

question

Most helpful comment

This would be a good feature to add Date to the DayViewFacade, because the content of the decorator might be dependent on the date. I have very similar case, where I would need a text under the day.

All 18 comments

You must initiate the decorator class with a collection of dates that should be consumed by the decorator. Check here for an example : https://github.com/prolificinteractive/material-calendarview/blob/master/docs/DECORATORS.

Sorry sir i can't view your link. I get 404 error

oops @quocthinh212 https://github.com/prolificinteractive/material-calendarview/blob/master/docs/DECORATORS.md

basically you shouldn't care about the date of the view you want to decorate, you just pass the view you KNOW you will be decorating on create. i.e.

public class MyStringDayDecorator implements DayViewDecorator {

private final String mMyString;
private final ArrayList<CalendarDay> dates;

public EventDecorator(String myString, ArrayList<CalendarDay> dates) {
    this.mMyString = myString;
    this.dates = dates.
}

@Override
public boolean shouldDecorate(CalendarDay day) {

    return dates.contains(day);
}

@Override
public void decorate(DayViewFacade view) {
    //do whatever you want right here 
    //add the string 
}

}

Though, now that I'm thinking about it I'm now sure how you would at text unless you changed the source a bit - although not sure how well text would look

Yes i know that. But in deCorate(Dayviewfacade view)
I need get current date in this viewdecord.
I want to get customs string from this date and decore this view with this string

You can see my picture.
I want use deCorate to buid lunnar calendar. I have function convert solar date to lunnar date.
But in decorate function i can't get dynamic date with current view!

screenshot_2016-04-18-13-45-24

This would be a good feature to add Date to the DayViewFacade, because the content of the decorator might be dependent on the date. I have very similar case, where I would need a text under the day.

The same issue for me.
I need to decorate days in different way depending on events that I have on this day.
For example Day1 has event A so I should be green, but Day2 should be red.

To implement this, I need CalendarDay in decorate() callback.
Without it the whole idea of decorators looks useless as for me :(

Since decorators aren't meant to be dynamic (based on day), you need to know which days your decorators will be responsible for at constructor time. That is to say you'll likely have a dozen or so decorators if you have lots of different types of days. Thats perfectly fine. When initializing your calendar UI, you should have a method to parse through your collection of events, whatever they may be, and build a collection of CalendarDays to pass to each individual decorator. Then in the decorator, it knows to decorate a current day IF that day is in the collection it was passed.

Thanks for quick reply Elliot!
I thought about the solution you provided, but it's very limited indeed.
In my case I have the list of different events for every day.
I need to display the list of them inside CustomDrawable and display the counter.

If I'm not mistaken, the decorators were built this way because the calendar's decorators are parsed A LOT when rendering the views. So the simpler, the better - adding logic to each decorator gets timely and can cause performance issues. I do see how your case isn't easily solved by the current implementation. I haven't looked into it but would love to see PR roll through with these changes :)

Please see my code:

public void addLunarDecord(Calendar cal){
cal.add(Calendar.MONTH,-1);
ArrayList listDecor = new ArrayList();
for (int i = 0; i < 93; i++) {
CalendarDay day = CalendarDay.from(cal);
listDecor.add((new LunarDecorator(Color.parseColor("#2980b9"), day)));
cal.add(Calendar.DATE, 1);
}
widget.addDecorators(listDecor);

}

And:

public

class LunarDecorator implements DayViewDecorator {

private int color;
private CalendarDay date;


public LunarDecorator(int color, CalendarDay dates) {
    this.color = color;
    this.date = dates;
}

@Override
public boolean shouldDecorate(CalendarDay day) {
  return date != null && day.equals(date);
}

@Override
public void decorate(DayViewFacade view) {

    Calendar cal = Calendar.getInstance();
    cal.set(date.getYear(), date.getMonth() + 1, date.getDay());

    float tz = TimeUnit.HOURS.convert(cal.getTimeZone().getRawOffset(), TimeUnit.MILLISECONDS);
    YMD tmp = LunarCalendarUtil.convertSolar2Lunar(date.getYear(), date.getMonth()+1, date.getDay(), tz);

    String ngayAm = tmp.day+"";
    if(tmp.day == 1){
        ngayAm = tmp.day+"/"+tmp.month;
        color = Color.RED;
    }

    if(tmp.day == 15){
        ngayAm = tmp.day+"";
        color = Color.RED;
    }


    final float scale = Resources.getSystem().getDisplayMetrics().density;
    view.addSpan(new TextSpan(ngayAm + "", color));


}

}

To give more examples for why this is really quite needed (in a sense), consider the case of applying a bubble with a number to represent something like "number of messages received on this day" (etc). To do this with the current implementation, you'd have to create a new decorator for every number, which quickly becomes impractical (realistically, you'd have to do something like have decorators for 1, 2, ... 9+ or so).

And some things are just flat out impossible. Imagine if you wanted to treat this like a heatmap of sorts. Maybe each day has some likelihood of an event occurring and we want to visualize that by making some days a brighter red to show the event is highly likely to occur and then blue means almost no chance. This kind of gradient would be easy to calculate if we could lookup what something about the day, but with the current way decorators work, it is quite impractical to do this (you'd have to have discretize the gradient).

I'm curious if this is something the developers are hard set about or inclined to accept a pull request over? Given the age of the issue, I assume it's not planned to fix.

I wish the decorate() can distinguish what day it will decorate, too many decorators result to slow animation. I tried to create a dynamic decorator for every single day of a month and remove the previous decorators but still, it runs slow.

This problem also faces me in decoration of day in MaterialCalendar.

Thanks for posting this issue.

any good solution to this?? I m facing the same issues.
I need to add a different color background for events in a calendar..

Here is my code, one decorator and you pass the color and the days to paint as params

public class DateDecorator implements DayViewDecorator {
    private int color = 0;
    private final HashSet<CalendarDay> dates;
    private ColorDrawable drawable;
    private Context context;

    public DateDecorator(Context context, int color, Collection<CalendarDay> dates) {
        this.context = context;
        this.color = color;
        this.dates = new HashSet<>(dates);
        drawable = new ColorDrawable(color);
    }

    @Override
    public boolean shouldDecorate(CalendarDay day) {
        return dates.contains(day);
    }

    @Override
    public void decorate(DayViewFacade view) {
        view.addSpan(new DotSpan(10, color));
        }
    }
}

I have to create days list with each kind of event
on Activity...

calendar_mv.addDecorator(new DateDecorator(getActivity(), getColor(getActivity(), R.color.primary_darker), generic_events_list));
calendar_mv.addDecorator(new DateDecorator(getActivity(), getColor(getActivity(), R.color.green), task_events_list));
calendar_mv.addDecorator(new DateDecorator(getActivity(), getColor(getActivity(), R.color.red), exam_events_list));
calendar_mv.addDecorator(new DateDecorator(getActivity(), getColor(getActivity(), R.color.black), absence_events_list));

Hi. you guy can add single event(date, count) instead of add list of event, so u can solve problem

Was this page helpful?
0 / 5 - 0 ratings