2017-10-08 87 views
0

我想每秒更改绘制的矩形的颜色。我有下面的代码来做到这一点。自定义视图忽略延迟

private Runnable mRunnable; 
private int mIndex; 
... 

public BlinkingView(Context context) { 
    this(context, null); 

    mRunnable = new Runnable() { 
     @Override 
     public void run() { 
      long currentMillis = System.currentTimeMillis(); 
      Log.d("Tag", "Millis Dif -- " + (mIndex== 0 ? "GREEN" : "RED") + " :: " + (currentMillis - lastMillis)); 
      lastMillis = currentMillis; 

      // Set the paint color to be drawn. 
      mColoredRectPaint.setColor(mIndex++ % 2 == 1 ? Color.RED : Color.GREEN); 

      // Update the view. 
      invalidate(); 

      // Run again. 
      postDelayed(mRunnable, 1000); 
     } 
    }; 

    post(mRunnable); 
} 

@Override 
protected void onDraw(Canvas canvas) { 
    super.onDraw(canvas); 

    // Draw the colored rectangle 
    canvas.drawRect(mLeft, mTop, mRight, mBottom, mColoredRectPaint); 

    // Draw a boarder rectangle. 
    canvas.drawRect(mStrokeLeft, mStrokeTop, mStrokeRight, mStrokeBottom, mOuterRectPaint); 
} 

但是,只有每隔调用postDelayed被延迟。我注销每次调用runnable的run方法之间的毫秒数。

D/Tag: DURATION -- GREEN :: 1000 
D/Tag: DURATION -- RED :: 1 
D/Tag: DURATION -- GREEN :: 1002 
D/Tag: DURATION -- RED :: 3 
D/Tag: DURATION -- GREEN :: 1001 
D/Tag: DURATION -- RED :: 3 
D/Tag: DURATION -- GREEN :: 1001 
D/Tag: DURATION -- RED :: 2 

所以每隔呼叫被推迟。任何想法为什么?

+0

延迟通常会有误差范围,如果我没有记错 – JoxTraex

+0

我认为这保证这将是该时间之后,但不一定正是时候。而且,整整一秒也是一个相当大的误差。 –

+0

你应该澄清的一件事是你所指的日志。并显示代码完全是你写的。 – JoxTraex

回答

0

使用Timer

private Timer myTimer; 

myTimer = new Timer(); 
myTimer.schedule(new TimerTask() 
{ 
    @Override 
    public void run() 
    { 
      // Set the paint color to be drawn. 
      mColoredRectPaint.setColor(mIndex++ % 2 == 1 ? Color.RED : Color.GREEN); 

      // Update the view. 
      invalidate(); 
    } 
}, 0, 1000); 

更新:

您还可以使用线程管理器:

mThread=new Thread(new Runnable() { 
     @Override 
     public void run() { 

      while (!Thread.currentThread().isInterrupted()) { 

       // Set the paint color to be drawn. 
       mColoredRectPaint.setColor(mIndex++ % 2 == 1 ? Color.RED : Color.GREEN); 

       // Update the view. 
       postInvalidate(); 

       switch (state){ 
        case 1: 
         Thread.sleep(500); 
         break; 
        case 2: 
         Thread.sleep(1000); 
         break; 
        default: 
         Thread.sleep(3000); 
         break; 
       } 
      } 
     } 
    }); 
    mThread.start(); 
+0

这可能会持续一段时间,但如果我想为500毫米显示1色,而另一个显示为1000则该怎么办?或者提供一个自定义时间计划?这不是灵活的。 –

+0

@JBlaz动态持续时间你可以使用线程。 –

0

的问题是不是与自定义视图。问题出在Handler。我看到你的帖子,并试图运行一个简单的代码:

final Handler handler = new Handler(); 
mRunnable = new Runnable() { 
    @Override 
    public void run() { 
     long currentTime = System.currentTimeMillis(); 
     System.err.println(currentTime - lastTime); 
     lastTime = currentTime; 
     handler.postDelayed(mRunnable, 1000); 
    } 
}; 
handler.post(mRunnable); 

令人惊讶的是,它也给出了相同的结果。

结论:如果您希望功能完全相同,请不要使用处理程序。您可能需要直接使用Thread

0

看看下面的代码我解释过,可以通过你的测试用例。

int tick = 0; 
Handler handler = new Handler(); 
handler.postDelayed(new Runnable() { 
    @Override 
    public void run() { 
     tick++; 
     if(tick%2==0) { 
      handler.postDelayed(this, 500); 
      // Set the paint color to be drawn. 
      mColoredRectPaint.setColor(Color.RED); 
     } else { 
      mColoredRectPaint.setColor(Color.GREEN); 
      handler.postDelayed(this, 1000); 
     } 
     // Update the view. 
     invalidate(); 
    } 
}, 1000)