2011-10-26 21 views
4

私の活動では、3つのカスタムビューがスタックされています。 下位のものはSurfaceViewフルスクリーンで、中間のものはGridViewから派生し、onDrawをオーバーライドしてカスタムグラフィックを追加します。カスタムビューでinvalidate()を呼び出すと、onDraw(Canvas c)が呼び出されません。

トップビューは直接ビューから派生し、画面の一角にあり、他の2つのビューを制御するノブとして機能します(これは問題のあるビューです)。アニメーション保留がある場合は、各描画サイクルの後にビューが自動無効化すべきで、理想的

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サイクルを発生させる必要があります。 Devツールの "show screen updates"の使用画面をクリックすると、画面の無効化/更新サイクルが発生しないことがわかります。 汚れた矩形を指定しても効果はありません。

したがって、この無効化/描画サイクルがなぜ機能しないのかを知るためには、どのようなアイディアが必要ですか?

答えて

0

あなたのビューでプラ​​イベートクラスでこれを試してみてください。考え方は、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() 
     }); 
    } 

    } 

} 
+0

最後に、私が使用した解決策はこれと似ていました – andijcr

2

私はこの状況に遭遇し、またinvalidate()onDraw()をもう一度呼び出さないと疑った。

ビジネスコードが簡略化された後、デッドループが発生することがわかりました。反復回数が多すぎると、UIスレッドがブロックされます。

私のアドバイスは、UIスレッドがスムーズに先に進むようにすることです。

関連する問題