2014-11-05 63 views
0

我編程了a simple test app,其中Drawable對象(下面屏幕截圖中的黃色半透明瓷磚)可以在可滾動和可縮放(通過使用Matrix)上拖動畫布:在畫布上拖動Drawable - works,但位置不準確

Emulator screenshot

這裏是代碼處理拖動:

private Drawable mDragged = null; 
private float mPrevX; 
private float mPrevY; 

public boolean onTouchEvent(MotionEvent e) { 
    // Convert touch coordinates to Canvas coordinates 
    float[] point = new float[] {e.getX(), e.getY()}; 
    Matrix inverse = new Matrix(); 
    mMatrix.invert(inverse); 
    inverse.mapPoints(point); 
    float x = point[0]; 
    float y = point[1]; 

    switch (e.getAction()) { 
    case MotionEvent.ACTION_DOWN: 
     Drawable tile = hitTest(x, y); 
     if (tile != null) { 
      mDragged = tile; 
      mPrevX = x; 
      mPrevY = y; 
      return true; 
     } 
    break; 
    case MotionEvent.ACTION_MOVE: 
     if (mDragged != null) { 
      float dX = x - mPrevX; 
      float dY = y - mPrevY; 
      mPrevX = x; 
      mPrevY = y; 

      Rect rect = mDragged.copyBounds(); 
      rect.left += dX; 
      rect.top += dY; 
      rect.right = rect.left + mDragged.getIntrinsicWidth(); 
      rect.bottom = rect.top + mDragged.getIntrinsicHeight(); 
      mDragged.setBounds(rect); 

      invalidate(); 
      return true; 
     } 
    break; 
    case MotionEvent.ACTION_UP: 
    case MotionEvent.ACTION_CANCEL: 
     if (mDragged != null) { 
      mDragged = null; 
      return true; 
     } 
    break; 
    } 
    // Handle Canvas scrolling and scaling here 
} 

它的工作原理,但我有一個問題 - 當我觸摸瓷磚,然後拖動它周圍 - 瓷磚從離開我手指(或使用Android模擬器時從我的鼠標指針)。

I.e.被拖動的Drawable與手指(或鼠標指針 - 在上面的屏幕截圖中可以看到)之間的距離增加,同時被拖動。

這不能是a multi-touch related issue - 因爲在仿真器上只有一次觸摸。

這裏的根本原因是什麼?

回答

1

只是一種預感在這裏,但它可能是由於兩件事情被一起配製:

  1. 你的座標是float值,但Rectint值,這可能會導致一些四捨五入問題
  2. 在每個ACTION_MOVE事件中,您正在添加(可能)取整的值,並更改基線(mPrevX & mPrevY),而不是計算您從第一次開始拖動的絕對距離

當拖動開始時(包括光標位置的偏移量),我將存儲圖塊的當前位置,然後將所有移動計算基於該點。

+1

+1謝謝。問題被'rect.left + = Math.round(dX)'治癒,但我也會實施你的第二個建議。 – 2014-11-05 15:26:03