KitKat SDK 支持一种称为 quick scale 的新型缩放手势。用户可以双击和滑动来缩放视图,而不是需要两根手指来缩放。您可以在 Chrome 和地图应用程序中看到这一点。
Chrome 和地图都区分双击(像以前一样放大相关内容区域)和双击滑动(允许您用一根手指任意缩放)。
在引擎盖下,ScaleGestureDetector 使用 GestureDetector 检测双击并开始寻找相应的滑动。
我的问题是如何模仿 Chrome 和地图,同时检测双击和这种双击滑动手势,但不能同时检测两者。也就是说,我想区分正常的双击(不滑动)和双击滑动。
我有一个 GestureDetector 和一个 ScaleGestureDetector 被馈送到我视图中的所有触摸事件。目前,当我进行双击滑动时, GestureListener.onDoubleTap() 和 ScaleGestureListener.onScaleBegin() 都会触发。 onDoubleTap() 首先被触发,因此无法取消 ScaleGestureListener 中的处理事件。
我看到两种可能的解决方案,都不是很干净:
处理这个问题的最佳方法是什么?
这个派对有点晚了,但快速缩放更像是一个未完成的双击,第二次点击变成了拖动,就像:
向下轻敲,向上轻敲,向下轻敲,移动
看来你对quick scale的解释是:
向下轻敲,向上轻敲,向下轻敲,向上轻敲,向下轻敲,移动
如果你只在第二个动作上注册一个简单的双击,这会让你的问题变得容易得多。当第二个向上动作发生时,您只需要弄清楚在第二个点击周期内是否发生了拖动。如果手势识别器不适合你,你可以通过检查 getScaledTouchSlop 来手动完成。
此外,复制 ScaleGestureDetector 可能没有您想的那么糟糕——github 上到处都是“兼容”项目,这些项目基本上是更新 SDK 版本中功能的反向移植。
我用几个标志解决了这个问题:
var inQuickScale: Boolean = false
var inUnfinishedDoubleTab: Boolean = false
private inner class GestureListener : GestureDetector.SimpleOnGestureListener() {
override fun onDoubleTap(e: MotionEvent): Boolean {
inUnfinishedDoubleTab = true
inQuickScale = true
return true
}
override fun onDoubleTapEvent(e: MotionEvent): Boolean {
if (inUnfinishedDoubleTab) {
if (e.action == MotionEvent.ACTION_UP) {
inUnfinishedDoubleTab = false
inQuickScale = false
// Handle double tap here
return true
}
}
return false
}
}
private inner class ScaleGestureListener : ScaleGestureDetector.SimpleOnScaleGestureListener() {
override fun onScaleBegin(detector: ScaleGestureDetector): Boolean {
inUnfinishedDoubleTab = false
return true
}
override fun onScaleEnd(detector: ScaleGestureDetector) {
inQuickScale = false
}
override fun onScale(detector: ScaleGestureDetector): Boolean {
if (inQuickScale) {
// Handle quick scale here
} else {
// Handle regular scale here
}
return true
}
}