自定义View上的android – invalidate()不会导致调用onDraw(Canvas c)

对于我的活动,我使用3个自定义视图堆叠.

较低的一个是SurfaceView全屏,中间的一个是从GridView派生的,并覆盖onDraw以添加自定义图形.

顶部直接来自View,位于屏幕的一角,充当旋钮以控制其他两个视图(这是有问题的视图).

要在此视图中添加自定义动画,我使用了以下模式:

public class StubKnobView extends View{

    private Drawable knob;
    private Point knobPos;
    private float rotation;
    private boolean needsToMove;

    public void moveKnob(){
            /* ...various calculations... */
            this.needsToMove=true;
            invalidate();   //to notify the intention to start animation
    }

    private void updateAnimation(){
        /* ........... */
        this.needsToMove= !animationComplete;
        invalidate();        
    }

    @Override
    protected void onDraw(Canvas canvas) {
        int saveCount=canvas.getSaveCount();
        canvas.save();
        canvas.rotate(this.rotation, this.knobPos.x, this.knobPos.y );
        this.knob.draw(canvas);
        canvas.restoreToCount(saveCount);
        if(this.needsToMove){
            updateAnimation();
        }
    }
}

理想情况下,如果有动画待定,则在每个绘制周期后视图应自动无效.

现在这不起作用,强制动画我必须触摸屏幕以导致onDraw循环.
使用开发工具的“显示屏幕更新”,我看到没有屏幕无效/更新周期发生,除了我点击屏幕.
指定脏矩形也没有效果.

那么,任何想法在哪里知道为什么这个无效/绘制周期不起作用的意图?

最佳答案 在View中使用私有类尝试类似的操作.我们的想法是不要从onDraw()中调用invalidate().相反,将其发布在正在运行的队列中.在View构造函数中实例化私有类,然后在需要动画时调用animateKnob.start().然后onDraw()可以专注于绘图.

public void moveKnob(){

  // update the state to draw... KnobPos, rotation
  invalidate()

}


private class AnimateKnob{
   public void start(){
      // Do some calculations if necessary 
      // Start the animation
      MyView.this.post( new Runnable() {
        stepAnimation()
      });
   }

   public void stepAnimation(){
     // update the animation, maybe use an interpolator.
     // Here you could also determine if the animation is complete or not

     MyView.this.moveKnob();

     if( !animationComplete ){
       // Call it again
       MyView.this.post( new Runnable() {
          stepAnimation()
       });
     }

   } 

}
点赞