Android,如何在绘图画布中重绘具有相同时差的点?

时间:2012-06-23 06:56:13

标签: android time android-canvas redraw

在android中开发绘画画布应用程序时,我需要跟踪所有点并且必须在另一个画布中重绘它。现在我能够跟踪所有点,但是在绘制和重绘的情况下不知道如何同步点绘图,即用户应该在绘图中同时重绘点。我怎样才能做到这一点?

1 个答案:

答案 0 :(得分:0)

不确定这是否是您正在寻找的那种答案,但我会用一种时间戳记录事件,实际上是下一点的时间差。类似的东西:

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

由你决定你想要的时机精确程度。秒到毫秒的精度应该足够好。您可以将deltaTime解释为应该绘制此点的时间或应该绘制下一个点的时间(我将在我的示例中使用后者)。

使用deltaTime而不是直接时间戳的一些原因是,它允许您检查实际上很长的暂停,并且您将不得不在回放中计算增量时间。同时使用它作为long应该为你提供足够的空间来进行真正冗长的暂停,并允许你使用Handler类接受一个长整数来表示在执行之前要等待的毫秒数。

 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
     }

此代码远非完整或防弹。也就是说,你需要稍后暂停或重新开始重绘,因为用户切换了活动或打了电话等。我也没有实现你在哪里或如何获得画布对象的细节(我想你有那个部分到现在为止)。此外,您可能希望跟踪前一个点,这样您就可以将矩形发送到View.postInvalidate,因为重绘一小部分屏幕要比重绘它快得多。最后我没有实现任何清理,需要根据需要销毁处理程序和点列表。

可能有几种不同的方法,有些可能比这更好。如果您担心触摸事件之间的长时间暂停,只需添加deltaTime的检查,如果它大于10秒,则将其覆盖为10秒。防爆。 handler.sendEmptyMessage(MSG_DRAW_NEXT, Math.min(p.deltaTime, 100000));我建议使用常量而不是硬编码的数字。

希望这有帮助