-1

半静的(めったに変更されない)ビットマップを作成する非ビューアイコンを受け入れるカスタムビュー(ディスプレイ)を作成しました。アイデアは、キャンバスに印刷するためにディスプレイにいくつかのアイコンを渡すことです。私の問題は、ディスプレイにアイコンビットマップを実際にキャンバスに描画させることができないことです。

以下のコードは、私が持っているものの実用的な例です。(動作するということは、正しく実行されることを意味します。私が望むものを印刷するということではありません)

public class AndroidTestoActivity extends Activity {
    @Override public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        FrameLayout fl = new FrameLayout(this);
        Display tv = new Display(this); 
        tv.setLayoutParams(new LayoutParams(200, 200));
        fl.addView(tv);
        setContentView(fl);
    }

    public class Display extends View {
        Paint vPaint = new Paint();
        Icon item = new Icon();

        public Display(Context context) {
            super(context);
            vPaint.setStyle(Paint.Style.FILL_AND_STROKE);
            vPaint.setColor(0x0ff000000);
            setBackgroundColor(0xffffffff);
        }

        @Override public void onDraw(Canvas canvas) {
            canvas.scale(200, 200);
            item.onDraw(canvas);
            canvas.drawLine(0.0f, 0.0f, 1.0f, 1.0f, vPaint);
        }
    }

    public class Icon {
        Bitmap myImage;
        Paint mPaint = new Paint();

        public Icon() {
            myImage = Bitmap.createBitmap(50, 50, Bitmap.Config.ARGB_8888);
            mPaint.setStyle(Style.FILL);
            mPaint.setColor(0xffff0000);
            Canvas c = new Canvas(myImage);
            c.scale(50, 50);
            c.drawCircle(0.5f, 0.5f, 0.5f, mPaint);
        }

        public void onDraw(Canvas canvas) {
            canvas.drawBitmap(myImage, 0, 0, null);
        }
    }
}

このコードは、左上から右下に線を印刷し、0,0から50、50まで直径50pxの円を描く必要があります。代わりに、私が得るのは線だけです。ただし、ビットマップをファイルに印刷すると、ファイルは正確に出力されます。

何が起こっているのかについて誰かが手がかりを持っていますか?

編集
私の質問を明確にするために、私はDisplayViewよりも大幅に小さいビットマップを作成しています。ビットマップをDisplayViewに描画しようとすると、ビットマップは描画したものとはまったく異なり、適切に拡大縮小されません。キャンバスがビットマップを正しく描画しないのはなぜですか?

UPDATE
DiplayのonDrawメソッドで、行items.onDraw(canvas);を前に移動しましたcanvas.scale(200, 200);。これで、テスト円が正しく描画されます。以前の方法で円を描くことを完全に無視するために行うこのような単純な変更は何ですか?

4

4 に答える 4

1

結局のところ、私は@MartinAsenovがほとんど正しかった。最終的に必要になったのは、キャンバスを拡大縮小して通常どおりに描画する(または保存して復元した場合は後)に、キャッシュされたすべてのビットマップを描画することでした。キャンバスの拡大縮小については、それでも必要だと思います(他のウィジェットはすべて、問題なく描画する前に幅と高さに拡大縮小します)。

これが最終的な作業テストアクティビティです。

public class AndroidTestoActivity extends Activity {
    @Override public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        FrameLayout fl = new FrameLayout(this);
        Display tv = new Display(this); 
        tv.setLayoutParams(new LayoutParams(200, 200));
        fl.addView(tv);
        setContentView(fl);
    }

    public class Display extends View {
        Paint vPaint = new Paint();
        Icon item = new Icon();

        public Display(Context context) {
            super(context);
            vPaint.setStyle(Paint.Style.FILL_AND_STROKE);
            vPaint.setColor(0x0ff000000);
            setBackgroundColor(0xffffffff);
        }

        @Override public void onDraw(Canvas canvas) {
            item.onDraw(canvas);
            canvas.save(Canvas.MATRIX_SAVE_FLAG);
            canvas.scale(getWidth(), getHeight());

            canvas.drawLine(0.0f, 0.0f, 1.0f, 1.0f, vPaint);
            canvas.restore();
        }
    }

    public class Icon {
        Bitmap myImage;
        Paint mPaint = new Paint();

        public Icon() {
            myImage = Bitmap.createBitmap(50, 50, Bitmap.Config.ARGB_8888);
            mPaint.setStyle(Style.FILL);
            mPaint.setColor(0xffff0000);
            Canvas c = new Canvas(myImage);
            c.scale(50, 50);
            c.drawCircle(0.5f, 0.5f, 0.5f, mPaint);
        }

        public void onDraw(Canvas canvas) {
            canvas.drawBitmap(myImage, 50, 50, null);
        }
    }
}
于 2012-04-09T16:55:14.423 に答える
0

コードを見ると、主な問題は、座標が0f..1fであると想定しているが、真実は0f..width / 0f..heightであると思います-floatは、サブピクセルを持つために使用されます

于 2012-04-06T23:20:25.007 に答える
0

私の推測では、円が大きくなりすぎて(200倍にスケーリング)、その座標が負になります(つまり、左上隅が(-5、-10)になります)。Androidシステムは負の座標でビューを描画しません(これを実現したい場合は、onMeasure()メソッドをオーバーライドする必要があります)

于 2012-04-09T17:51:55.333 に答える
0

キャンバスの仕組みを少し混乱させていると思います(直感的ではないため、混乱しやすいです)。ビットマップをパラメータとしてCanvasを呼び出す方法では、ビットマップがペイントされているものとして扱われることになります。そのため、ビットマップのサイズに制約されます。パラメータなしでキャンバス(空のキャンバス)を作成し、それにビットマップを描画した場合、実際にはビットマップは変更されず、キャンバスに描画されるだけです。そのような状況では、長方形内の任意の場所にビットマップを描画し、その周りに円を描画できます(またはその他の必要なもの)。

また、onDrawメソッドをオーバーライドして、そのキャンバス(コールバックを呼び出すときに渡される)を収集し、必要なものをそのキャンバスに描画することもできます...これが実際に画面に表示されるキャンバスです。それにアクセスするための最も簡単な方法。

于 2012-04-09T17:54:47.277 に答える