[Android开发]二、自定义View手势监听ScaleGestureDetector使用教程

        上节说到了GestureDetector,接下来介绍下ScaleGestureDetector

        首先我们知道 View 主要自带了 设置单击、长按等监听,一般来说就够用了,但我们有时自定义View 需要更多的功能,ScaleGestureDetector主要是解决双指捏合的手势监听,常见场景就是相册图片捏合时对图片的放大缩小

        先直接上干货~

public interface OnScaleGestureListener {
    public boolean onScale(@NonNull ScaleGestureDetector detector);
    
    public boolean onScaleBegin(@NonNull ScaleGestureDetector detector);

    public void onScaleEnd(@NonNull ScaleGestureDetector detector);
}

        ScaleGestureDetector  只有这一个监听器,下面来介绍下监听器各个回调的详解~

一、OnScaleGestureListener 回调方法介绍

public boolean onScale(@NonNull ScaleGestureDetector detector);

        onScale 是捏合过程的回调, 回调的 detector 我们主要用到 

        1、detector.focusX 是放缩时围绕的焦点 x 坐标

        2、detector.focusY 是放缩时围绕的焦点 y 坐标

        3、detector.scaleFactor 是放缩的倍数,这里我们要结合onScale的返回值来看如何使用该值。如果返回 true 就代表我已消费此次回调事件,下次再返回时就是相对上次的放缩倍数;如果返回 false 就代表我不消费此次回调事件,下次返回时是相对最后一次消费事件时(即上次返回true)的放缩倍数,所以如果写死了返回false就是相对最开始的放缩倍数。

public boolean onScaleBegin(@NonNull ScaleGestureDetector detector);

        onScaleBegin 是开始捏合时的回调,在此必须返回true,如果不返回true,那么接下来您将不会得到onScale的回调

public void onScaleEnd(@NonNull ScaleGestureDetector detector);

        onScaleEnd 很简单字面意思就是结束了捏合放缩

二、接下来看下如何使用

class CustomView2(context: Context, attrs: AttributeSet?) : View(context, attrs),
    ScaleGestureDetector.OnScaleGestureListener{

    private val scaleGestureDetector = ScaleGestureDetector(context,this)


    override fun onTouchEvent(event: MotionEvent): Boolean {
        return scaleGestureDetector.onTouchEvent(event)
    }

}

        使用起来也很简单,只是需要把 View 的 onTouchEvent 的方法用 ScaleGestureDetector 接管即可

        这里额外说明一下,其实我们在写自定义触摸时,几乎都要在onTouchEvent返回true的,而ScaleGestureDetector的onTouchEvent也是写死了返回true的。这跟Android 的时间分发机制是有关系的,主要原因就在ACTION_DOWN返回true才可以消费接下来的事件序列,返回false就代表不再消费接下来的事件序列了,而其他事件返回什么是无所谓的。

三、接下来看下如何结合上节提到的GestureDetector来使用

class CustomView(context: Context, attrs: AttributeSet?) : View(context, attrs),
    GestureDetector.OnGestureListener, GestureDetector.OnDoubleTapListener, ScaleGestureDetector.OnScaleGestureListener {
    private val gestureDetector = GestureDetectorCompat(context,this).apply {
        setOnDoubleTapListener(this@CustomView)
    }
    private val scaleGestureDetector = ScaleGestureDetector(context,this)

    override fun onTouchEvent(event: MotionEvent): Boolean {
        scaleGestureDetector.onTouchEvent(event);
        if (!scaleGestureDetector.isInProgress){
            gestureDetector.onTouchEvent(event)
        }
        return true
    }
}

        这里介绍下 ScaleGestureDetector 的 isInProgress 返回 true 意思就是正在识别为双指捏合了,反之返回 false 说明没有在捏合,所以不在捏合时,应该使用 GestureDetector来处理触摸事件。

        这里可能会有人想为什么优先使用 ScaleGestureDetector 来处理触摸事件呢?细想一下当用户双指在屏幕上捏合时,当然优先处理捏合事件了,当不是双指捏合事件时,就应该由 GestureDetector 来处理了。这样做符合大多数的产品设计思路的,除非是比较奇葩的。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值