This is a migrated thread and some comments may be shown as answers.

RadCalendar events, EventRenderer,(custom painting of events)

6 Answers 201 Views
Calendar
This is a migrated thread and some comments may be shown as answers.
This question is locked. New answers and comments are not allowed.
zabdiel
Top achievements
Rank 1
zabdiel asked on 15 Dec 2014, 03:22 AM
Hello telerik. I just want to ask if there is any sample code that shows how to use a custom EventRenderer for painting of the events in a calendar cell? I have an attached file that represents a sample calendar cell, with small-rounded-colored shapes below that represents events. Below is my sample code so far. any help would be greatly appreciated. Thanks.



private RadCalendarView radCalendar;

    @Override
    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_rad_calendar_sample);

        radCalendar = (RadCalendarView) findViewById(R.id.calendarView);
       
        Calendar calendar = Calendar.getInstance();
        long eventStart = calendar.getTimeInMillis();
        calendar.add(Calendar.HOUR, 1);
        long eventEnd = calendar.getTimeInMillis();


        Event event1 = new Event("", eventStart, eventEnd);
        Event event2 = new Event("", eventStart, eventEnd);
        Event event3 = new Event("", eventStart, eventEnd);

        List<Event> events = new ArrayList<Event>();
        events.add(event1);
        events.add(event2);
        events.add(event3);


        radCalendar.getEventAdapter().setRenderer(new MyEventRenderer(this));
        radCalendar.getEventAdapter().setEvents(events);
        radCalendar.notifyDataChanged();
    }   

   private class MyEventRenderer extends EventRenderer {

        private int shapeRadius;
        private Paint paint;

        public MyEventRenderer(Context context) {
            super(context);

            paint = new Paint();
            paint.setAntiAlias(true);
        }

        @Override
        public void renderEvents(Canvas canvas, CalendarCell cell) {


            shapeRadius = cell.getWidth() > cell.getHeight() ? cell.getHeight() : cell.getWidth();
            shapeRadius *= 0.45;

            Rect borderRect = cell.calcBorderRect();
            int centerX = (borderRect.left + borderRect.right) / 2;
            int centerY = (borderRect.top + borderRect.bottom) / 2;

            paint.setColor(Color.RED);
            MyEventRenderer.this.drawCircle(canvas, centerX, centerY);
        }

        private void drawCircle(Canvas canvas, int x, int y) {
            canvas.drawCircle(x, y, (int) (this.shapeRadius * 0.9f), this.paint);
        }
    }








6 Answers, 1 is accepted

Sort by
0
Accepted
Todor
Telerik team
answered on 16 Dec 2014, 11:51 AM
Hi Zabdiel,

Thank you for your interest in RadCalendarView.

Since your image seems to have four events in different colors, I updated your events' setup:

Event event1 = new Event("", eventStart, eventEnd);
event1.setEventColor(Color.parseColor("#C8E140"));
Event event2 = new Event("", eventStart, eventEnd);
event2.setEventColor(Color.parseColor("#227665"));
Event event3 = new Event("", eventStart, eventEnd);
event3.setEventColor(Color.parseColor("#414B95"));
Event event4 = new Event("", eventStart, eventEnd);
event4.setEventColor(Color.parseColor("#FF0000"));
 
List<Event> events = new ArrayList<Event>();
events.add(event1);
events.add(event2);
events.add(event3);
events.add(event4);

Then, in order to correctly render them, you need to do this in you EventRenderer implementation:

public class MyEventRenderer extends EventRenderer {
    private Paint paint;
 
    public MyEventRenderer(Context context) {
        super(context);
 
        paint = new Paint();
        paint.setAntiAlias(true);
    }
 
    @Override
    public void renderEvents(Canvas canvas, CalendarCell cell) {
 
        int desiredOffset = 20;
        int shapeRadius = 10;
        int locationX = desiredOffset;
        int locationY = cell.getHeight() - desiredOffset;
        for(Event e : cell.getEvents()) {
            if(locationX >= cell.getWidth()) {
                return;
            }
            this.paint.setColor(e.getEventColor());
            canvas.drawCircle(locationX, locationY, shapeRadius, this.paint);
            locationX += shapeRadius + desiredOffset;
        }
    }
}

In short, the renderEvents method is called for each cell that contains events and the information about them is contained within the cell itself, you simply need to iterate over each event and draw a proper representation on the presented canvas.

I hope this information helps.

Regards,
Todor
Telerik
 

Check out the Telerik Platform - the only platform that combines a rich set of UI tools with powerful cloud services to develop web, hybrid and native mobile apps.

 
0
Kyle
Top achievements
Rank 1
answered on 15 Jul 2015, 03:33 PM

I've tried to follow this but I am running into issues.  I only ever have 1 event per day maximum, but I'm looking to be able to position the event color and text starting in the bottom corner of the cell.  I copied the above code pretty much exactly, but I'm only ever getting a colored circle drawn in the very first cell, as seen in the attached image.  It looks like they are all just drawing the circle over one another, or drawing it in the same place.

 

 

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
 
import com.telerik.widget.calendar.CalendarDayCell;
import com.telerik.widget.calendar.events.Event;
import com.telerik.widget.calendar.events.EventRenderer;
 
public class MyEventRenderer extends EventRenderer {
    private Paint paint;
 
    public MyEventRenderer(Context context) {
        super(context);
 
        paint = new Paint();
        paint.setAntiAlias(true);
    }
 
    @Override
    public void renderEvents(Canvas canvas, CalendarDayCell cell) {
 
        int desiredOffset = 20;
        int shapeRadius = 10;
        int locationX = desiredOffset;
        int locationY = cell.getHeight() - desiredOffset;
        for(Event e : cell.getEvents()) {
            if(locationX >= cell.getWidth()) {
                return;
            }
            this.paint.setColor(e.getEventColor());
            canvas.drawCircle(locationX, locationY, shapeRadius, this.paint);
            locationX += shapeRadius + desiredOffset;
            String test = "test";
        }
 
    }
}

 

Here is where I have my events and set my adapter

calendar = new RadCalendarView(myActivity);
 
        calendar.setHorizontalScroll(true);
        calendar.setSelectionMode(CalendarSelectionMode.Single);
        calendar.getAdapter().setTodayCellBorderColor(Color.WHITE);
        calendar.getAdapter().setTodayCellTypeFace(Typeface.DEFAULT);
        calendar.getAdapter().setTodayCellTextColor(Color.GRAY);
        calendar.getEventAdapter().setRenderer(new MyEventRenderer(myActivity));

 

The images below are using the exact same data set.

 

Thank you,

 

0
Todor
Telerik team
answered on 17 Jul 2015, 03:25 PM
Hi Kyle,

Thank you for writing.

This is an old thread and indeed since then there was a change in the way the calendar cells are rendered and this change reflects in the code from my previous post. What's changed is that now the canvas that you receive as a parameter is the whole calendar, while it used to be only the part taken by a particular cell. This means that, as you have correctly observed, all dots are drawn one over the other since the coordinates start from the top-left corner of the calendar and not by the corner of each cell. The solution is simple, you just have to adjust the coordinates for drawing depending on the current cell's coordinates:

public class MyEventRenderer extends EventRenderer {
 
    private Paint paint;
 
    public MyEventRenderer(Context context) {
        super(context);
 
        paint = new Paint();
        paint.setAntiAlias(true);
    }
 
    @Override
    public void renderEvents(Canvas canvas, CalendarDayCell cell) {
 
        int desiredOffset = 20;
        int shapeRadius = 10;
        int locationX = cell.getLeft() + desiredOffset;
        int locationY = cell.getTop() + cell.getHeight() - desiredOffset;
        for(Event e : cell.getEvents()) {
            this.paint.setColor(e.getEventColor());
            canvas.drawCircle(locationX, locationY, shapeRadius, this.paint);
            locationX += shapeRadius + desiredOffset;
        }
    }
}

I hope this information helps. And thanks again for writing in this thread so others can also see how the code should be updated.

Regards,
Todor
Telerik
Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Feedback Portal and vote to affect the priority of the items
0
Kyle
Top achievements
Rank 1
answered on 17 Jul 2015, 07:37 PM

Thank you very much!  It looks much better now.  My next question, is how do I render the event title next to the rendered shape?

 

 

0
Kyle
Top achievements
Rank 1
answered on 20 Jul 2015, 12:21 PM

So I got text to render by using something like this:

this.paint.setTextSize(20);
this.paint.setFakeBoldText(true);
canvas.drawText(e.getTitle(),(float)locationX+20,(float)locationY+8,this.paint);

 

The issue i'm having now, is that I need to support both normal android devices, very small screens, and tablets.  The above render looks great on normal size phone screens, however is is much much too large on the small screens and the circles overtake the cell.  Are the integers we are using Px instead of DP?  If so, is there anyway to handle multiple screen sizes with a custom renderer other than create multiple instances?

 

0
Todor
Telerik team
answered on 22 Jul 2015, 11:35 AM
Hi Kyle,

Here's how you can create a size that is dependent on the screen size:

float value = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, 20, Resources.getSystem().getDisplayMetrics());
this.paint.setTextSize(value);

Now depending on the current device's screen, the value will be correctly converted.

I hope this information helps.

Regards,
Todor
Telerik
Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Feedback Portal and vote to affect the priority of the items
Tags
Calendar
Asked by
zabdiel
Top achievements
Rank 1
Answers by
Todor
Telerik team
Kyle
Top achievements
Rank 1
Share this question
or