2011-05-11 71 views
2

有人可以幫我幾件關於mapview im試圖構建。 我有一個需要畫布並在其中繪製位圖的渲染器。 我創建了一個視圖,並在構造函數中我創建:ANDROID - MapView

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. 我如何處理縮放手勢?有了這個代碼時,用我的手指縮小圖像是「拖」到左上角...

即時通訊新的android(和java),所以任何幫助preciated。

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

和中點功能 -

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

thanx爲anwser戴夫!你能否請給我提供更多的問題。我在屏幕上有一張地圖。我知道中心點。當我執行捏縮放我知道中點。圖像被拉伸或縮小,中心點以中點大小移動,而手指離中點更遠離中點或遠離中點。這意味着我將不得不根據縮放手勢來計算中心。我希望你明白我的意思。我檢查了谷歌地圖的Android和他們保持中心點極端錯誤...任何建議? – no9

+0

我認爲你遇到了影響觸摸事件的X,Y座標的ZOOM問題。您需要做的是使用INVERTED矩陣將事件X,Y點反轉,例如 - 'float [] pts = new float [2]; \t \t \t pts [0] = event.getX(); \t \t \t pts [1] = event.getY(); \t \t \t Matrix 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)處理縮放手勢,您需要處理ACTION_POINTER_DOWN,ACTION_MOVE & ACTION_POINTER_UP事件。這裏有一個很好的教程 - How to use Multi-touch in Android

要小心,當你放大的ImageView的,它的任何後續圖紙需要在X,Y座標也縮放,使用矩陣mapPoints(PTS)方法來做到這一點。

+0

我發佈的代碼(類MyMapView)擴展了View。我嘗試使用該示例中的代碼,但我無法讓它在擴展視圖的類上工作。使用我的代碼進行縮放工作,只需在執行縮放時將圖像「粘」到左上角。放大(縮小手勢)釋放後,我將再次渲染畫布。另外...我如何在我的代碼中實現雙擊和兩個按鈕水龍頭?該視圖沒有方法,所以我想我需要實現gesturedetector?我在這裏朝着正確的方向走嗎? – no9

+0

這是你發佈的問題的一個單獨的問題。如果您想要點擊事件的答案,請發佈一個單獨的問題。 – daveD