在画布上拖动Drawable - 有效,但位置不准确

时间:2014-11-05 13:49:50

标签: android canvas android-canvas drag android-drawable

我编写了a simple test app,其中Drawable个对象(下面屏幕截图中的黄色半透明图块)可以在可滚动和可伸缩(通过使用矩阵)画布上拖动:

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模拟器时从我的鼠标指针)。

即。被拖动的Drawable和手指(或鼠标指针 - 在上面的屏幕截图中可以看到)之间的距离会增加,而它被拖动。

这不能是a multi-touch related issue - 因为模拟器上只有一次触摸。

这里的根本原因是什么?

1 个答案:

答案 0 :(得分:1)

这里只是预感,但这可能是因为两件事情在一起复合:

  1. 您的坐标为float个值,但Rect包含int个值,这可能会导致一些舍入问题
  2. 在每个 ACTION_MOVE 事件中,您要添加(可能)舍入的值,并更改基线(mPrevX& mPrevY),而不是计算绝对距离你刚开始拖动的地方
  3. 我会在拖动开始时存储图块的当前位置(包括从光标位置偏移),然后将所有移动计算基于该点。