2

誰かが私が構築しようとしているmapviewimに関するいくつかのことを手伝ってくれませんか。キャンバスを取得してビットマップを描画するレンダラーがあります。ビューを作成し、コンストラクターで次を作成します。

bitmap = Bitmap.createBitmap(windowWidth, windowHeight, Bitmap.Config.ARGB_8888);
canvas = new Canvas(bitmap);
drawable = new BitmapDrawable(bitmap);
drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight());
this.Render();

onDrawメソッドで私はこれを持っています:

super.onDraw(canvas);
canvas.save();
canvas.translate(mPosX, mPosY);
canvas.scale(mScaleFactor, mScaleFactor);
drawable.draw(canvas);
canvas.restore();

今、私はパンとズームを実装したいと思います(現在、保存されたタイルなしで動作しています)これが私のonTouchです:

mScaleDetector.onTouchEvent(ev);

final int action = ev.getAction();
switch (action & MotionEvent.ACTION_MASK) {

case MotionEvent.ACTION_DOWN: {
    this.hasPanned = false;
    final float x = ev.getX();
    final float y = ev.getY();

    mLastTouchX = x;
    mLastTouchY = y;
    mActivePointerId = ev.getPointerId(0);
    break;
}

case MotionEvent.ACTION_MOVE: {
    final int pointerIndex = ev.findPointerIndex(mActivePointerId);
    final float x = ev.getX(pointerIndex);
    final float y = ev.getY(pointerIndex);

    if (!mScaleDetector.isInProgress()) {
        final float dx = x - mLastTouchX;
        final float dy = y - mLastTouchY;

        mPosX += dx;
        mPosY += dy;

        invalidate();
    }

    mLastTouchX = x;
    mLastTouchY = y;

    break;
}

case MotionEvent.ACTION_UP: {
    mActivePointerId = INVALID_POINTER_ID;
    if (this.mDownTouchX != this.mLastTouchX && this.mDownTouchY != mLastTouchY)
        this.hasPanned = true;
    break;
}

case MotionEvent.ACTION_CANCEL: {
    mActivePointerId = INVALID_POINTER_ID;
    break;
}

case MotionEvent.ACTION_POINTER_UP: {
    final int pointerIndex = (ev.getAction() & MotionEvent.ACTION_POINTER_INDEX_MASK) 
            >> MotionEvent.ACTION_POINTER_INDEX_SHIFT;
    final int pointerId = ev.getPointerId(pointerIndex);
    if (pointerId == mActivePointerId) {
        final int newPointerIndex = pointerIndex == 0 ? 1 : 0;
        mLastTouchX = ev.getX(newPointerIndex);
        mLastTouchY = ev.getY(newPointerIndex);
        mActivePointerId = ev.getPointerId(newPointerIndex);
    }
    break;
}
}
return true;

これが私が望むものと私が抱えている問題です:

  1. パンするとき、距離をピクセル単位で計算したいので、レンダラーが画像を再度レンダリングするときにそれを伝えることができます。これはどのように達成されますか?ACTION_DOWNの座標を記憶し、ACTION_UPの新しい座標と比較することによって?
  2. パンが完了したら(そして画像が再レンダリングされたら)、キャンバス(画像)を元の位置に戻したいと思います。現在、ペインのままです(canvas.translateのため?)
  3. ズームジェスチャを処理するにはどうすればよいですか?このコードを使用すると、指でズームアウトすると、画像が左上隅に向かって「ドラッグ」されます...

私はアンドロイド(およびジャバ)で新しいので、どんな助けも高く評価されます。

4

2 に答える 2

2

ズームコードがCanvasをズームしても正しく移動しない場合は、間違ったCanvas.scale()メソッドを呼び出している可能性があります。あなたが使用している方法は-のようです

scale(float sx, float sy)

そして私はあなたが使う必要があると思います-

scale(float sx, float sy, float px, float py)

sx&syは明らかにx&yスケールファクターです(私は通常それらを同じ値に設定します)。pxとpyは、ズーム操作の中心点です。たとえば、MotionEvent.ACTION_DOWNイベント座標とMotionEvent.ACTION_POINTER_DOWNイベント座標の間の中点です。

私のMotionEvent.ACTION_POINTER_DOWNハンドラーで-を呼び出します

midPoint(mid, event);

midは-として定義されます

private PointF mid = new PointF();

そしてmidPoint関数は-

private void midPoint(PointF point, MotionEvent event) 
{
   float x = event.getX(0) + event.getX(1);
   float y = event.getY(0) + event.getY(1);
   point.set(x / 2, y / 2);
}

したがって、MotionEvent.ACTION_MOVEハンドラーでは、-を呼び出します。

Canvas.scale(sx, sy, mid.x, mid.y);
于 2011-05-31T19:13:33.967 に答える
1

1) はい、ACTION_DOWN で

PontF downAt = new PointF(event.getX(), event.getY());

ACTION_UP では、ピクセル間の差を計算します。

2) MapView は ImageView とは動作が異なります。使用するMapViewの場合

mapView.getController().animateTo(GeoPoint);

しかし、ImageView からサブクラス化し、onDraw(Canvas canvas) メソッドをオーバーライドして、Canvas に直接アクセスしたいと本当に思っています。次に、Matrix を使用して移動とズームを処理します。

imageView.setScaleType(ImageView.ScaleType.MATRIX);
Matrix imageMatrix = new Matrix();
imageMatrix.postTranslate(xMove, yMove);
imageMatrix.postScale(scaleX, scaleY, midX, midY);
imageView.setImageMatrix(imageMatrix);

3) ZOOM ジェスチャを処理するには、ACTION_POINTER_DOWN、ACTION_MOVE、および ACTION_POINTER_UP イベントを処理する必要があります。ここに本当に良いチュートリアルがあります - Androidでマルチタッチを使用する方法

imageView を ZOOM するときは注意してください。それ以降の描画では、X、Y 座標もスケーリングする必要があります。これを行うには、Matrix mapPoints(Pts) メソッドを使用します。

于 2011-05-27T20:26:28.527 に答える