web-dev-qa-db-ja.com

Android View.onDraw()には常にクリーンなキャンバスがあります

アニメーションを描いてみました。そのために、Viewを拡張し、onDraw()メソッドをオーバーライドしました。私が期待するのは、onDraw()が呼び出されるたびに、キャンバスはそのままの状態になり、クリアするか、一部を描画するかを選択できることです(これは、SurfaceViewを使用したときの動作です。 )しかし、キャンバスが戻ってくるたびに、すでにクリアされています。クリアできない方法はありますか?または、前の状態をビットマップに保存して、そのビットマップを描画してからその上に描画できるようにすることもできますか?

17
CaseyB

方法があるかどうかはわかりません。しかし、私のカスタムビューでは、onDraw()が呼び出されるたびにすべてを再描画するか、ビットマップに描画してから、ビットマップをキャンバスに描画します(質問で提案したように)。

これが私がそれをする方法です

class A extends View {

    private Canvas canvas;
    private Bitmap bitmap;

    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        if (bitmap != null) {
            bitmap .recycle();
        }
        canvas= new Canvas();
        bitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
        canvas.setBitmap(bitmap);
    }
    public void destroy() {
        if (bitmap != null) {
            bitmap.recycle();
        }
    }
    public void onDraw(Canvas c) {
      //draw onto the canvas if needed (maybe only the parts of animation that changed)
      canvas.drawRect(0,0,10,10,Paint);

      //draw the bitmap to the real canvas c
      c.drawBitmap(bitmap, 
          new Rect(0,0,bitmap.getWidth(),bitmap.getHeight()), 
          new Rect(0,0,bitmap.getWidth(),bitmap.getHeight()), null);
    }
}
28
dweebo

基本ビューとsurfaceViewの違いを確認するには、 ここ を参照してください。 surfaceViewには描画専用のレイヤーがあり、これは以前に描画したものを追跡していると思います。これで、本当に基本的なビューでそれを実行したい場合は、 マップビューの項目化されたオーバーレイ の例のように、描画する各項目を配列に配置してみることができます。ほぼ同じように機能するはずです

1
Sephy

あなたの期待は現実とジブしません:)キャンバスはあなたがそれを残した方法ではありませんが、代わりに空白になります。描画するオブジェクトのArrayList(canvas.drawCircle()、canvas.drawBitmap()など)を作成してから、OnDraw()のArrayListを反復処理できます。私はグラフィックプログラミングに不慣れですが、これを小規模に使用しました。たぶんもっと良い方法があります。

0
Matt Shirilla