如何在 Android 中同时进行双击和平移?
How to make double tap and panning work at same time, in Android?
所以我试图让我的观点以多种不同的方式工作,应该有:
- 多点触控缩放
- 用于平移的 Touchlistener
- 双击恢复缩放
- 或者如果它已经恢复,它将缩放双击的位置。
目前,其他一切正常,但是当我双击并按住第二次并继续移动它时,代码首先按 restores/zooms
然后 panning starts
的方式工作。
所以因为zoomscale,有时候会先改变canvas的大小,然后再开始平移。在注意到双击后我应该怎么做才能启用平移?或者检查双击的最后一次点击是否继续移动并跳过 zoom/restore 之类的东西?我的代码看起来像这样的自动取款机。我试图在双击后 return false 但它并没有真正影响......是否会有像设置 ignoreMultiTouch
到 true
,但双击或平移?
@Override
public boolean onTouchEvent(MotionEvent ev) {
if(mgestureDetector.onTouchEvent(ev)){
mOnTouchEventWorkingArray[0] = ev.getX();
mOnTouchEventWorkingArray[1] = ev.getY();
mOnTouchEventWorkingArray = scaledPointsToScreenPoints(mOnTouchEventWorkingArray);
ev.setLocation(mOnTouchEventWorkingArray[0], mOnTouchEventWorkingArray[1]);
mScaleDetector.onTouchEvent(ev);
final int action = ev.getAction();
switch (action & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_DOWN: {
final float x = ev.getX();
final float y = ev.getY();
mLastTouchX = x;
mLastTouchY = y;
// Save the ID of this pointer
mActivePointerId = ev.getPointerId(0);
break;
}
case MotionEvent.ACTION_MOVE: {
// Find the index of the active pointer and fetch its position
final int pointerIndex = ev.findPointerIndex(mActivePointerId);
final float x = ev.getX(pointerIndex);
final float y = ev.getY(pointerIndex);
final float dx = x - mLastTouchX;
final float dy = y - mLastTouchY;
mPosX += dx;
mPosY += dy;
mTranslateMatrix.preTranslate(dx, dy);
mTranslateMatrix.invert(mTranslateMatrixInverse);
mLastTouchX = x;
mLastTouchY = y;
normal = false;
invalidate();
break;
}
case MotionEvent.ACTION_UP: {
mActivePointerId = INVALID_POINTER_ID;
break;
}
case MotionEvent.ACTION_CANCEL: {
mActivePointerId = INVALID_POINTER_ID;
break;
}
case MotionEvent.ACTION_POINTER_UP: {
// Extract the index of the pointer that left the touch sensor
final int pointerIndex = (action & MotionEvent.ACTION_POINTER_INDEX_MASK) >> MotionEvent.ACTION_POINTER_INDEX_SHIFT;
final int pointerId = ev.getPointerId(pointerIndex);
if (pointerId == mActivePointerId) {
// This was our active pointer going up. Choose a new
// active pointer and adjust accordingly.
final int newPointerIndex = pointerIndex == 0 ? 1 : 0;
mLastTouchX = ev.getX(newPointerIndex);
mLastTouchY = ev.getY(newPointerIndex);
mActivePointerId = ev.getPointerId(newPointerIndex);
}
break;
}
}
}
return true;
}
private class ScaleListener extends ScaleGestureDetector.SimpleOnScaleGestureListener {
@Override
public boolean onScale(ScaleGestureDetector detector) {
mScaleFactor *= detector.getScaleFactor();
if (detector.isInProgress()) {
mFocusX = detector.getFocusX();
mFocusY = detector.getFocusY();
}
mScaleFactor = Math.max(0.75f, Math.min(mScaleFactor, 3.0f));
mScaleMatrix.setScale(mScaleFactor, mScaleFactor,
mFocusX, mFocusY);
mScaleMatrix.invert(mScaleMatrixInverse);
invalidate();
requestLayout();
return true;
}
}
private class GestureListener extends GestureDetector.SimpleOnGestureListener {
@Override
public boolean onDown(MotionEvent e) {
return true;
}
// event when double tap occurs
@Override
public boolean onDoubleTap(MotionEvent e) {
if (!normal) {
restore();
} else {
zoomToSpot(e);
}
return false;
}
@Override
public boolean onDoubleTapEvent(MotionEvent e) {
return true;
}
}
所以我让我的代码处理这些小东西,首先我添加了双击布尔值
public boolean onDoubleTap(MotionEvent e) {
if (!normal) {
restore();
} else {
zoomToSpot(e);
}
doubleclicked = true;
return true;
}
然后我制作了两个不同的 onTouchEvents 并设置第一个仅在 doubleclicked 为 false 时才起作用。当屏幕上没有手指时,第二个将设置 doubleclicked false。
public boolean onTouchEvent(MotionEvent ev) {
final int action = ev.getAction();
if (!doubleclicked) {
switch (action & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_DOWN: {
//something...
}
} else {
switch (action & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_UP: {
doubleclicked = false;
break;
}
}
}
所以我试图让我的观点以多种不同的方式工作,应该有:
- 多点触控缩放
- 用于平移的 Touchlistener
- 双击恢复缩放
- 或者如果它已经恢复,它将缩放双击的位置。
目前,其他一切正常,但是当我双击并按住第二次并继续移动它时,代码首先按 restores/zooms
然后 panning starts
的方式工作。
所以因为zoomscale,有时候会先改变canvas的大小,然后再开始平移。在注意到双击后我应该怎么做才能启用平移?或者检查双击的最后一次点击是否继续移动并跳过 zoom/restore 之类的东西?我的代码看起来像这样的自动取款机。我试图在双击后 return false 但它并没有真正影响......是否会有像设置 ignoreMultiTouch
到 true
,但双击或平移?
@Override
public boolean onTouchEvent(MotionEvent ev) {
if(mgestureDetector.onTouchEvent(ev)){
mOnTouchEventWorkingArray[0] = ev.getX();
mOnTouchEventWorkingArray[1] = ev.getY();
mOnTouchEventWorkingArray = scaledPointsToScreenPoints(mOnTouchEventWorkingArray);
ev.setLocation(mOnTouchEventWorkingArray[0], mOnTouchEventWorkingArray[1]);
mScaleDetector.onTouchEvent(ev);
final int action = ev.getAction();
switch (action & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_DOWN: {
final float x = ev.getX();
final float y = ev.getY();
mLastTouchX = x;
mLastTouchY = y;
// Save the ID of this pointer
mActivePointerId = ev.getPointerId(0);
break;
}
case MotionEvent.ACTION_MOVE: {
// Find the index of the active pointer and fetch its position
final int pointerIndex = ev.findPointerIndex(mActivePointerId);
final float x = ev.getX(pointerIndex);
final float y = ev.getY(pointerIndex);
final float dx = x - mLastTouchX;
final float dy = y - mLastTouchY;
mPosX += dx;
mPosY += dy;
mTranslateMatrix.preTranslate(dx, dy);
mTranslateMatrix.invert(mTranslateMatrixInverse);
mLastTouchX = x;
mLastTouchY = y;
normal = false;
invalidate();
break;
}
case MotionEvent.ACTION_UP: {
mActivePointerId = INVALID_POINTER_ID;
break;
}
case MotionEvent.ACTION_CANCEL: {
mActivePointerId = INVALID_POINTER_ID;
break;
}
case MotionEvent.ACTION_POINTER_UP: {
// Extract the index of the pointer that left the touch sensor
final int pointerIndex = (action & MotionEvent.ACTION_POINTER_INDEX_MASK) >> MotionEvent.ACTION_POINTER_INDEX_SHIFT;
final int pointerId = ev.getPointerId(pointerIndex);
if (pointerId == mActivePointerId) {
// This was our active pointer going up. Choose a new
// active pointer and adjust accordingly.
final int newPointerIndex = pointerIndex == 0 ? 1 : 0;
mLastTouchX = ev.getX(newPointerIndex);
mLastTouchY = ev.getY(newPointerIndex);
mActivePointerId = ev.getPointerId(newPointerIndex);
}
break;
}
}
}
return true;
}
private class ScaleListener extends ScaleGestureDetector.SimpleOnScaleGestureListener {
@Override
public boolean onScale(ScaleGestureDetector detector) {
mScaleFactor *= detector.getScaleFactor();
if (detector.isInProgress()) {
mFocusX = detector.getFocusX();
mFocusY = detector.getFocusY();
}
mScaleFactor = Math.max(0.75f, Math.min(mScaleFactor, 3.0f));
mScaleMatrix.setScale(mScaleFactor, mScaleFactor,
mFocusX, mFocusY);
mScaleMatrix.invert(mScaleMatrixInverse);
invalidate();
requestLayout();
return true;
}
}
private class GestureListener extends GestureDetector.SimpleOnGestureListener {
@Override
public boolean onDown(MotionEvent e) {
return true;
}
// event when double tap occurs
@Override
public boolean onDoubleTap(MotionEvent e) {
if (!normal) {
restore();
} else {
zoomToSpot(e);
}
return false;
}
@Override
public boolean onDoubleTapEvent(MotionEvent e) {
return true;
}
}
所以我让我的代码处理这些小东西,首先我添加了双击布尔值
public boolean onDoubleTap(MotionEvent e) {
if (!normal) {
restore();
} else {
zoomToSpot(e);
}
doubleclicked = true;
return true;
}
然后我制作了两个不同的 onTouchEvents 并设置第一个仅在 doubleclicked 为 false 时才起作用。当屏幕上没有手指时,第二个将设置 doubleclicked false。
public boolean onTouchEvent(MotionEvent ev) {
final int action = ev.getAction();
if (!doubleclicked) {
switch (action & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_DOWN: {
//something...
}
} else {
switch (action & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_UP: {
doubleclicked = false;
break;
}
}
}