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

sgtfey8w  于 2023-04-18  发布在  Android
关注(0)|答案(2)|浏览(112)

KitKat SDK支持一种名为快速缩放的新型缩放手势。用户可以双击和滑动来缩放视图,而不是需要两个手指来缩放。您可以在Chrome和Map应用程序中看到这一点。
Chrome和Map都区分了双击(如前所述,可以放大相关内容区域)和双击滑动(允许您用一根手指任意缩放)。
在引擎盖下,ScaleGestureDetector使用GestureDetector来检测双字母并开始寻找相应的滑动。
我的问题是如何模仿Chrome和Map,检测双击和双击滑动手势,但不是同时检测两者。也就是说,我想区分普通的双击(没有滑动)和双击滑动。
我有一个GestureDetector和一个ScaleGestureDetector,在我的视图上提供所有触摸事件。目前,当我进行双点滑动时,GestureListener.onDoubleTap()和ScaleGestureListener.onScaleBegin()都会触发。onDoubleTap()首先被触发,因此无法取消处理ScaleGestureListener中的事件。
我看到了两种可能的解决方案,但都不是很干净:

  • 从Android源代码中复制ScaleGestureDetector,并向ScaleGestureListener接口添加一个新的回调函数,例如onDoubleTapConfirmed()(双击,不滑动)。
  • 给onDoubleTap()添加一个小的延迟,这样我们就可以在事件被触发后的X毫秒内处理它。如果onScaleBegin()在延迟结束前被触发,取消处理onDoubleTap()事件,转而开始处理刻度。

最好的解决办法是什么?

yws3nbqq

yws3nbqq1#

这个派对有点晚了,但快速规模更像是一个未完成的双击,第二次点击变成了拖动,类似于:
拍下拍上拍下移动
你对快速缩放的解释似乎是:
拍下,拍上,拍下,拍上,拍下,移动
如果你只在向下的第二个动作上注册一个普通的双击,这会让你的问题变得容易得多。当第二个动作向上发生时,你只需要弄清楚在第二个点击周期中是否发生了拖动。如果手势识别器对你不起作用,你可以通过检查getScaledTouchSlop来手动完成。
此外,复制ScaleGestureDetector可能没有你想象的那么糟糕-- github上到处都是“compat”项目,这些项目基本上是新SDK版本中功能的后移植。

cwtwac6a

cwtwac6a2#

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

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

相关问题