2011-05-11 5 views
2

ビルドしようとしているマップビューについていくつかお役立てください。 レンダラにキャンバスをとり、そこにビットマップを描画します。 私はビューを作成し、コンストラクタで、私が作成します。アンドロイド - MapView

onDrawメソッドで
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(); 

私はこの持っている:

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

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

mScaleDetector.onTouchEvent(ev);私はそれが再び画像をレンダリングするとき、私は私のレンダラを伝えることができるように、ピクセル単位での距離を計算したいパンとき

  1. :ここ

    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; 
    

    は私が好きで、私が持っている問題であろうものです。これはどのように達成されますか? ACTION_DOWNの座標を記憶し、ACTION_UPの新しい座標と比較することで?

  2. パンが完了したら(イメージが再レンダリングされる)キャンバス(イメージ)を元の位置に戻したいと思います。現在のところ(キャンバストランスレートのためパンニングされたままです)
  3. ズームジェスチャーはどのように処理しますか?このコードでは、指でズームアウトするときに、画像が左上隅にドラッグされます。

Imはどのようなヘルプもpreciateされています。

+0

ちょっと説明してください。ピンチズームを行うと、画像が左上隅に貼り付けられますか? – no9

+1

これが 'MapView'とどう関係しているのかは分かりません...あなたはそれについて詳述できますか? –

答えて

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); 

半ばは次のように定義される -

private PointF mid = new PointF(); 

と中間点の機能がある - 私のMotionEventでとても

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); 
} 

。私が呼び出すACTION_MOVEハンドラ -

Canvas.scale(sx, sy, mid.x, mid.y); 
+0

thanx!追加の問題でアドバイスをしていただけますか?私は画面上に地図を持っています。私は中心点を知っています。私がピンチズームを実行するとき、私は中間点を知っている。画像は伸び縮みし、中心点は中点のサイズだけ移動し、指は中点から中点に向かってまたは中心点から遠ざかる方向に移動する。つまり、ズームジェスチャに基づいて中心を計算する必要があります。私はあなたが私の意味を理解してくれることを願っています私はアンドロイド用のGoogleマップをチェックし、彼らは間違っている中心点を維持している...任意の提案? – no9

+0

私はあなたがタッチイベントのX、Y座標に影響を与えるズームに問題があると思います。あなたがする必要があるのは、INVERTED行列を使ってイベントXをマップし、Y点を逆にします。 - 'float [] pts =新しいfloat [2]; \t \t \t pts [0] = event.getX(); \t \t \t pts [1] = event.getY(); \t \t \tマトリックスinvertedMatrix = new Matrix(); \t \t \t transMatrix.invert(invertedMatrix); \t \t \t invertedMatrix.mapPoints(pts); int invX = pts [0]; int invY = pts [1]; ' 変換したX、Yを使用して実際の中間点を決定します。 – daveD

1

1)はい、ACTION_DOWNわずか

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

を行うとACTION_UPの画素間の差を計算します。

2)MapViewはImageViewとは異なる働きをします。 MapViewのためには、

mapView.getController().animateTo(GeoPoint); 

を使用しますが、私はあなたが本当にImageViewのサブクラスからキャンバスに直接アクセスするためのonDraw(キャンバスキャンバス)メソッドをオーバーライドしたいと思います。次に、マトリックスを使用して翻訳&ズームを処理します。

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イベントを処理する必要があります。 How to use Multi-touch in Android

あなたはImageViewのをズームするときにこれを行うにはマトリックスmapPoints(PTS)メソッドを使用し、その上に後続の描画もスケールX、Y座標を必要とし、注意してください - ここでは本当に良いチュートリアルがあります。

+0

投稿したコード(MyMapViewクラス)がViewを拡張します。私はそのサンプルからコードを使用してみましたが、私はそれを私のクラスでビューを拡張するように動作させることはできません。コードをズームすると、ズームを実行するときにイメージが左上隅に「接着」されます。ズーム(ピンチジェスチャー)が解除されると、私は再びキャンバスを描画します。また...私はどのように私のコードでダブルタップと2つのボタンタップを実装するのですか?ビューはメソッドを持っていないので、私はgesturedetectorを実装する必要があると思いますか?私はここに正しい方向に進んでいますか? – no9

+0

投稿した質問とは別の質問があります。タップイベントに回答したい場合は、別の質問を投稿してください。 anwser daveについては – daveD