0

より大きなものをデバッグするために非常に小さなテストを実行していますが、この問題の原因を突き止めるのに苦労しています。

ImageView、Canvas、および Bitmap があります。ImageView を初期化して Bitmap に設定し、次に Canvas をビットマップに設定します。

_image.setImageBitmap(bitmap);
Canvas canvas = new Canvas(bitmap);

次に、onTouchListener を _image にアタッチし、MotionEvent.ACTION_UP が検出されるのをリッスンします。その時点で、次のようにキャンバスに Rect を描画します。

Rect rect = new Rect((int)event.getX(),event.getY(),event.getX()+20,event.getY()+20);
Paint paint = new Paint();
paint.setColor(Color.RED);
canvas.drawRect(rect,paint);

さまざまなサイズのビットマップ画像でこれを試してみました.フルディスプレイよりも小さいものから、正確なサイズに非常に近いものまで. getX() でさまざまな変換を試みましたが、dp から dp に変換しようとして、代わりに getRawX/Y() を使用しました。基本的に、さまざまなソリューションがたくさんありますが、どれも機能していません。ビットマップのサイズと画面サイズの比率を取得し、それを乗算/除算してみました。この非常に単純な問題を解決できたものはありません。

おそらく、私はある時点で正しいアプローチを試み、それを単に間違って実装しただけです。Rect がどこに描画されるのか、タッチが発生した場所に描画するために必要な変換とその理由について、アドバイスをいただければ幸いです。「なぜ」は、これから学びたいからです。

編集:これは何が起こるかの概算です。赤い四角形は実際のタッチが発生する場所で、青はそれが描画される場所です。X=Y=0 から遠ざかるほどスケーリングします。また、使用している画像の幅と高さに応じてスケーリングされることにも気付きました。

例

4

2 に答える 2

1

実際のビットマップはビューよりも大きく、縮小されていると思います。ビットマップの座標で描画していて、そのビットマップが縮小されているため、場所も一致するように縮小されます。

もっとやりたいことは、ImageView のサブクラスを作成し、onTouchEvent() で受け取った位置に基づいて onDraw() で Rect を描画することです。または、計算を行って、ビュー サイズに対してビットマップがどれだけ縮小されているかを把握し、逆に座標を拡大することもできます。このタッチ可能な ImageView の簡単な実装は次のようになります。

public class DrawableImageView extends ImageView {
    private final int mRectSize;
    private final Paint mPaint;
    private final Rect mRect = new Rect();

    public DrawableImageView(Context context) {
        super(context);
        mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        mPaint.setColor(Color.RED);
        mRectSize = (int) (getResources().getDisplayMetrics().density * 20);
    }

    // Other constructors omitted for brevity

    @Override public boolean onTouchEvent(MotionEvent event) {
        if (event.getAction() == MotionEvent.ACTION_UP) {
            final int x = (int) event.getX();
            final int y = (int) event.getY();

            mRect.set(x, y, x + mRectSize, y + mRectSize);
            mRect.offset(-(mRectSize / 2), -(mRectSize / 2));

            invalidate();
            return true;
        } else {
            return super.onTouchEvent(event);
        }
    }

    @Override protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        canvas.drawRect(mRect, mPaint);
    }
}
于 2014-06-10T20:25:56.277 に答える