Question

On developing a painting canvas application in android, i need to track all the points and have to redraw it in another canvas. Now i am able to track all the points, but don't know how to synchronize the point drawing in case of draw and redraw ie the user should redraw the points at the same time gap as in the draw. How can i achieve this?

Was it helpful?

Solution

Not sure if this is the sort of answer you are looking for but I would record the events with a sort of timestamp, really a time difference to the next point. Something like:

class Point {
    int x;
    int y;
    long deltaTime;
}

Its up to you how precise you want to be with the timing. Second to millisecond precision should be good enough. You could interpret deltaTime as either the time until this point should be drawn or the time until the next point should be drawn (I'm going to use the latter in my example).

A few reasons to use a deltaTime instead of a direct timestamp is that it lets you check for really long pauses and you are going to have to compute the delta time anyways in playback. Also using it as a long should give you enough room for really lengthy pauses and lets you use the Handler class which accepts a long integer for the number of milliseconds to wait before executing.

 public class Redrawer implements Handler.callback {
     LinkedList<Point> points; //List of point objects describing your drawing
     Handler handler = new Handler(this); //Probably should place this in class initialization code
     static final int MSG_DRAW_NEXT = 0;

     public void begin(){
         //Do any prep work here and then we can cheat and mimic a message call
         //Without a delay specified it will be called ASAP but on another
         //thread
         handler.sendEmptyMessage(MSG_DRAW_NEXT); 
     }

     public boolean handleMessage(Message msg){
         //If you use the handler for other things you will want to
         //branch off depending on msg.what
         Point p = points.remove(); //returns the first element, and removes it from the list
         drawPoint(p);
         if (!points.isEmpty())
             handler.sendEmptyMessageDelayed(MSG_DRAW_NEXT, p.deltaTime);

     public void drawPoint(Point p){
         //Canvas drawing code here
         //something like canvas.drawPixel(p.x, p.y, SOMECOLOR);
         //too lazy to look up the details right now
         //also since this is called on another thread you might want to use
         //view.postInvalidate
     }

This code is far from complete or bullet-proof. Namely you will need to possibly pause or restart the redrawing at a later time because the user switched activities or got a phone call, etc. I also didn't implement the details of where or how you get the canvas object (I figure you have that part down by now). Also you probably want to keep track of the previous point so you can make a rectangle to send to View.postInvalidate as redrawing a small portion of the screen is much faster than redrawing it all. Lastly I didn't implement any clean-up, the handler and points list will need to be destroyed as needed.

There are probably several different approaches to this, some probably better than this. If you're worried about long pauses between touch events simply add a check for the deltaTime if its greater than say 10 seconds, then just override it to 10 seconds. Ex. handler.sendEmptyMessage(MSG_DRAW_NEXT, Math.min(p.deltaTime, 100000)); I'd suggest using a constant instead of a hard coded number however.

Hope this helps

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top