ScaleGestureDetector 的新“快速缩放”功能和 GestureListener 的 onDoubleTap() 之间的正确交互是什么?

问题描述 投票:0回答:2

KitKat SDK 支持一种称为 quick scale 的新型缩放手势。用户可以双击和滑动来缩放视图,而不是需要两根手指来缩放。您可以在 Chrome 和地图应用程序中看到这一点。

Chrome 和地图都区分双击(像以前一样放大相关内容区域)和双击滑动(允许您用一根手指任意缩放)。

在引擎盖下,ScaleGestureDetector 使用 GestureDetector 检测双击并开始寻找相应的滑动。

我的问题是如何模仿 Chrome 和地图,同时检测双击和这种双击滑动手势,但不能同时检测两者。也就是说,我想区分正常的双击(不滑动)和双击滑动。

我有一个 GestureDetector 和一个 ScaleGestureDetector 被馈送到我视图中的所有触摸事件。目前,当我进行双击滑动时, GestureListener.onDoubleTap() 和 ScaleGestureListener.onScaleBegin() 都会触发。 onDoubleTap() 首先被触发,因此无法取消 ScaleGestureListener 中的处理事件。

我看到两种可能的解决方案,都不是很干净:

  • 从 Android 源代码中复制 ScaleGestureDetector,并向 ScaleGestureListener 接口添加一个新的回调函数,例如 onDoubleTapConfirmed()(双击,无滑动)。
  • 向 onDoubleTap() 添加一个小的延迟,以便我们在事件触发后 X 毫秒处理事件。如果 onScaleBegin() 在延迟结束之前被触发,取消处理 onDoubleTap() 事件并开始处理比例尺。

处理这个问题的最佳方法是什么?

android android-4.4-kitkat gesture-recognition
2个回答
0
投票

这个派对有点晚了,但快速缩放更像是一个未完成的双击,第二次点击变成了拖动,就像:

向下轻敲,向上轻敲,向下轻敲,移动

看来你对quick scale的解释是:

向下轻敲,向上轻敲,向下轻敲,向上轻敲,向下轻敲,移动

如果你只在第二个动作上注册一个简单的双击,这会让你的问题变得容易得多。当第二个向上动作发生时,您只需要弄清楚在第二个点击周期内是否发生了拖动。如果手势识别器不适合你,你可以通过检查 getScaledTouchSlop 来手动完成。

此外,复制 ScaleGestureDetector 可能没有您想的那么糟糕——github 上到处都是“兼容”项目,这些项目基本上是更新 SDK 版本中功能的反向移植。


0
投票

我用几个标志解决了这个问题:


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
    }
}

© www.soinside.com 2019 - 2024. All rights reserved.