android-times-square
android-times-square copied to clipboard
Cannot reset decorators
I'm trying to reset decorators after certain action is performed in the app by calling calendarView.setDecorators(Collections.<CalendarCellDecorator>emptyList()); but it won't work, the decorators stay as I set them using custom decorator class. What's the solution to this? I don't want to re-initialize the entire calendar every time that action is performed.
Thanks for the report @basit-saeed. Will take a look soon. For now the workaround would just be re-initializing the calendar, but obviously that's unfortunate.
Thank you for looking into it @edenman. Re-initializing the calendar view was the first option that came in my mind but due to project constraints, I couldn't do it. I came up with a different solution, though. I created a default decorator class for the calendar, picked up disabled/enabled background colors from the calendar image in readme file, and decorated them that way.
Here's a sample code (and neccessary colors) if anyone wants to implement it. Be advised, it is a workaround and I just created it as a placeholder while an official solution is being developed (I hope :) ).
Colors:
<color name="calendar_default_disabled_background">#D7D9DB</color>
<color name="calendar_default_disabled_text">#9CA3A9</color>
<color name="calendar_default_enabled_bakcground">#F5F7F9</color>
<color name="calendar_default_enabled_text">#A8AFB4</color>
Decorator class:
public class CalendarEmptyDecorator implements CalendarCellDecorator {
private Context context;
private Date min;
private Date max;
public CalendarEmptyDecorator(Context context, Date min, Date max) {
this.context = context;
this.min = min;
this.max = max;
}
@Override
public void decorate(CalendarCellView calendarCellView, Date date) {
if(date.compareTo(min) != -1 && date.compareTo(max) != 1) {
calendarCellView.setBackgroundColor(this.context.getResources()
.getColor(R.color.calendar_default_enabled_bakcground));
calendarCellView.setTextColor(this.context.getResources()
.getColor(R.color.calendar_default_enabled_text));
}
else {
calendarCellView.setBackgroundColor(this.context.getResources()
.getColor(R.color.calendar_default_disabled_bakcground));
calendarCellView.setTextColor(this.context.getResources()
.getColor(R.color.calendar_default_disabled_text));
}
}
}
I'm haven't yet given it a style of selected date, though. Will look into it once I have some time.
The behavior I'm seeing isn't so much that you can't reset decorators. From my testing, you can override an existing decorator by applying a new decorator that applies to the same date(s).
The issue I am seeing is that if a decorator changes the drawable state of a cell, and that decorator is removed, the drawing performed by the decorator remains on the cell. Another side effect I am seeing of this is that the drawing from the decorator is not removed from a recycled view.
You can reproduce this using a bare calendar and the following decorator:
public class CurrentDayDecorator implements CalendarCellDecorator {
private Context context;
public CurrentDayDecorator(Context context) {
this.context = context;
}
@Override
public void decorate(CalendarCellView calendarCellView, Date date) {
if (LocalDate.now().equals(new LocalDate(date))) {
calendarCellView.setBackgroundColor(context.getResources().getColor(R.color.blue));
}
}
}
Every third month you should see a decorated cell.
Listed workaround is good in the short term.
Refactoring the decorator pattern to look something like this -- https://github.com/wokkaflokka/android-times-square/commit/939ce954284af3391e9f8cb86906b552f5624d0f -- worked for my use case.
My code is at production level. @edenman @JakeWharton please help.