Reputation: 22958
I have programmed a simple test app, where Drawable
objects (the yellow translucent tiles at the screenshot below) can be dragged around on a scrollable and scallable (by using Matrix) Canvas:
Here is the code handling dragging:
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
}
It works, but I have a problem - when I touch a tile and then drag it around - the tile departs from my finger (or from my mouse pointer, when using Android emulator).
I.e. the distance between the dragged Drawable
and the finger (or mouse pointer - as can be seen on the above screenshot) increases, while it is being dragged around.
This can't be a multi-touch related issue - because there is only single touch on the emulator.
What is the root cause here?
Upvotes: 0
Views: 391
Reputation: 8685
Just a hunch here, but it's probably due to two things being compounded together:
float
values, but the Rect
consists of int
values, which can cause some rounding issuesmPrevX
& mPrevY
) instead of calculating the absolute distance from where you first started draggingI would store the current position of the tile when dragging starts (including offset from the cursor position), and then base all the movement calculations off of that point.
Upvotes: 1