我有一个同时使用 SimpleOnScaleGestureListener 和 SimpleOnGestureListener 的应用程序。每当我进行缩放缩放时,我都会得到预期的onScale,但是当我抬起时,我看到一个奇怪的onScroll,它的起始位置是缩放缩放的开始位置,结束位置是缩放缩放的末尾。我的问题是,我可以防止伪造的 onScroll 吗?
这是代码:
@Override
public boolean onTouchEvent(MotionEvent event) {
// Log every event.
Log.d(TAG, Here.at() + String.format("Event: %d, Time: %d X: %f, Y: %f",
event.getAction(),
event.getEventTime(),
event.getX(),
event.getY()
));
boolean handled = mScaleDetector.onTouchEvent(event); // This appears to ALWAYS return true (online reference indicated that's what the Android code does).
handled |= mDetector.onTouchEvent(event);
handled |= super.onTouchEvent(event);
return handled;
}
private class ScaleListener extends ScaleGestureDetector.SimpleOnScaleGestureListener {
@Override
public boolean onScaleBegin(ScaleGestureDetector detector) {
// This is required. If absent, the scale gesture never starts.
Log.d(TAG, "In onScaleBegin");
mIgnoreNextDrag = true;
return true;
}
@Override
public boolean onScale(ScaleGestureDetector detector) {
Log.d(TAG, "In onScale");
mTimeScale.doScale(detector.getScaleFactor(), detector.getFocusY());
invalidate();
return true;
}
@Override
public void onScaleEnd(ScaleGestureDetector detector) {
Log.d(TAG, "In onScaleEnd");
}
}
private class GestureListener extends GestureDetector.SimpleOnGestureListener {
@Override
public boolean onScroll(MotionEvent me1, MotionEvent me2, float distanceX, float distanceY) {
Log.d(TAG, String.format("Motion Event 1: %d, Time: %d X: %f, Y: %f",
me1.getAction(),
me1.getEventTime(),
me1.getX(),
me1.getY()
));
Log.d(TAG, String.format("Event 2: %d, Time: %d X: %f, Y: %f",
me2.getAction(),
me2.getEventTime(),
me2.getX(),
me2.getY()
));
return true;
}
@Override
public boolean onSingleTapConfirmed(MotionEvent me) {
// Do tap processing.
return true;
}
@Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
// TODO: Future feature.
return true;
}
@Override
public boolean onDown(MotionEvent e) {
// This is required. If absent, the scroll gesture never starts.
return true;
}
}
这是 LogCat:
13:06:05.885: D/my-tag(4140): In View.onTouchEvent, Event: 0, Time: 183279420 X: 171.761444, Y: 918.160767
13:06:05.895: D/my-tag(4140): In View.onTouchEvent, Event: 261, Time: 183279420 X: 171.761444, Y: 918.160767
13:06:05.895: D/my-tag(4140): In onScaleBegin
13:06:05.895: I/ScaleGestureDetector(4140): TwScaleGestureDetector
13:06:05.915: D/my-tag(4140): In View.onTouchEvent, Event: 2, Time: 183279458 X: 171.761444, Y: 908.474365
13:06:05.915: D/my-tag(4140): In onScale
13:06:06.015: D/my-tag(4140): In View.onTouchEvent, Event: 2, Time: 183279542 X: 174.964783, Y: 857.584717
13:06:06.015: D/my-tag(4140): In onScale
13:06:06.105: D/my-tag(4140): In View.onTouchEvent, Event: 2, Time: 183279641 X: 232.242096, Y: 731.365662
13:06:06.105: D/my-tag(4140): In onScale
13:06:06.215: D/my-tag(4140): In View.onTouchEvent, Event: 2, Time: 183279740 X: 313.564514, Y: 595.412964
13:06:06.215: D/my-tag(4140): In onScale
13:06:06.225: D/my-tag(4140): In View.onTouchEvent, Event: 6, Time: 183279751 X: 313.564514, Y: 595.412964
13:06:06.225: D/my-tag(4140): In onScaleEnd
13:06:06.245: D/my-tag(4140): In View.onTouchEvent, Event: 2, Time: 183279774 X: 333.316528, Y: 487.607422
13:06:06.245: D/my-tag(4140): In onScroll, me1: 0, Time: 183279420 X: 171.761444, Y: 918.160767
13:06:06.245: D/my-tag(4140): In onScroll, me2 2: 2, Time: 183279774 X: 333.316528, Y: 487.607422
13:06:06.255: D/my-tag(4140): In View.onTouchEvent, Event: 2, Time: 183279784 X: 331.539551, Y: 488.496460
13:06:06.265: D/my-tag(4140): In onScroll, me1: 0, Time: 183279420 X: 171.761444, Y: 918.160767
13:06:06.265: D/my-tag(4140): In onScroll, me2 2: 2, Time: 183279784 X: 331.539551, Y: 488.496460
13:06:06.275: D/my-tag(4140): In View.onTouchEvent, Event: 1, Time: 183279794 X: 331.539551, Y: 488.496460
您可以看到第一个事件是第一根手指向下 (0 = ACTION_DOWN),然后是第二根手指向下 (261 = ACTION_POINTER_2_DOWN)。然后我们看到来自 onScaleBegin 调用的日志条目和来自缩放手势检测器本身的日志(不是来自我的代码)。在这一点上,我想我可以放心地假设缩放手势已经开始了。这完全符合预期。
随后是四个移动事件 (2 = ACTION_MOVE),每个事件后面紧跟着来自 onScale 的日志条目。这仍然符合预期。
然后我们看到一个指针向上事件 (6 = ACTION_POINTER_UP),然后是来自 onScaleEnd 的日志条目,仍然 AOK!(请注意,它是 6 而不是 262,因为我抬起手指的顺序与放下手指的顺序相同,因此首先抬起的是指针 1,而不是指针 2。)
现在奇怪的一点。
我们看到一个移动事件,它被 SimpleOnGestureListener 中的 onScroll 拾取。第一个参数 me1 具有缩放手势开始之前第一个向下事件的 x 和 y 坐标。第二个参数 me2 具有明显反映缩放手势停止后的位置的坐标。
在这个例子中,实际上还有第二个移动事件,它也被解释为滚动手势,同样是预缩放原点。使用上面的代码,我会在捏缩放后得到 1、2 或没有滚动事件。
(为了结束 LogCat,我们为第二根手指设置了一个最终向上事件 (1 = ACTION_UP),并且日志变得安静。)
那我做错了吗?如果 SimpleOnScaleGestureListener 从 isInProgress 返回 false,我只尝试调用 SimpleOnGestureListener,但没有任何乐趣。
有任何想法吗?
在此先感谢,并感谢社区中的所有人,这些年来我从该站点获得的大量信息!