Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

invalidate() on custom View does not cause onDraw(Canvas c) to be called

Tags:

android

view

For my activity i use 3 custom views stacked. the lower one is a SurfaceView fullscreen, the middle one is derived from GridView and overrides onDraw to add custom graphic.

The top one is derived directly from View, sits in a corner of the screen and act as a knob to control the others two views (this is the problematic view).

to add a custom animation to this view, i used this pattern:

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();
        }
    }
}

ideally, if there is an animation pending, after each drawing cycle the view should auto invalidate.

right now this doesn't work, to force the animation i have to touch the screen to cause a onDraw cycle. Using "show screen updates" of Dev tools I see that no screen invalidate/update cycle happen , apart when i click the screen. specifying the dirty rect also ha no effect.

So, any idea where to look to know why this invalidate/draw cycle does not work the way is intended?

like image 775
andijcr Avatar asked Nov 05 '22 12:11

andijcr


1 Answers

I encontered this situation, and also doubted that invalidate() doesn't make onDraw() called again.

After simplified the business codes, it's turn out that there is a dead loop - exactly too much iterations, which blocks the UI thread.

So, my advice is that make sure the UI thread going smoothly first.

like image 157
odys Avatar answered Nov 15 '22 04:11

odys