Android GestureDetector使用粗解

570 阅读5分钟

前言:GestureDetector该类主要用来处理自定义view或者其他场景的手势处理,该类由Android官方提供,粗解GestureDetector,方便自己巩固学习、后续复习。该篇文章不会过多的展示业务代码,这不是我的目的,主要对如何使用以及使用过程中,需要注意的点进行说明,并不是一篇攻略文,仅仅只是一篇描述文

如何使用

分两种情况来示例

如果只想处理双击,也需要实现 OnGestureListener 以及 OnDoubleTapListener,需要在 OnGestureListener监听的 onDown 方法中返回true消费事件。

1、只需要处理手势,不需要处理双击

class GestureView(context: Context, attrs: AttributeSet?) : View(context, attrs),
    GestureDetector.OnGestureListener {

    private val gestureDetector = GestureDetectorCompat(context, this)

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

     override fun onDown(e: MotionEvent): Boolean {
        //这里必须返回true,不然后续监听不会收到事件,等同于在ACTION_DOWN中返回true
        //有一种写法是
        return e.actionMasked == MotionEvent.ACTION_DOWN
        //但大多数情况,直接返回true即可
        return true
    }

    //显示按下效果,忽略父布局是不是滑动布局的影响,用户触摸到并且触摸时间到了100ms显示按下效果,
    override fun onShowPress(e: MotionEvent?) {
    }

    //处理单击,(如果gesture支持长按,那么只有在长按时间500毫秒内抬起才会被调用)
    override fun onSingleTapUp(e: MotionEvent?): Boolean {
        //返回true代表消费了这个点击事件,该返回值用于给系统做记录,对事件序列不会产生影响
        return false
    }

    //处理滑动,接收到的事件序列是ACTION_MOVE,
    //distanceX 与 distanceY 是这次事件跟上次事件的触摸点的距离,数值是用旧的触摸点减去新的触摸点得到
    override fun onScroll(
        downEvent: MotionEvent,
        currentEvent: MotionEvent,
        distanceX: Float,
        distanceY: Float
    ): Boolean {
        return false
    }

    //长按
    override fun onLongPress(e: MotionEvent?) {
    }

    //快速滑动view后松手触发,处理快滑/惯性滑动后的后续操作,跟onScroll配合使用,
    //velocityX velocityY 数值代表速率,单位时间内的位移
    override fun onFling(
        e1: MotionEvent?,
        e2: MotionEvent?,
        velocityX: Float,
        velocityY: Float
    ): Boolean {
        return false
    }
}

2、需要手势,也需要处理双击

class GestureView(context: Context, attrs: AttributeSet?) : View(context, attrs),
    GestureDetector.OnDoubleTapListener, GestureDetector.OnGestureListener {


    private val gestureDetector = GestureDetectorCompat(context, this)

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

    override fun onSingleTapConfirmed(e: MotionEvent): Boolean {
        return false
    }

    override fun onDoubleTap(e: MotionEvent?): Boolean {
        return false
    }

    override fun onDoubleTapEven t(e: MotionEvent?): Boolean {
        return false
    }


     override fun onDown(e: MotionEvent): Boolean {
        //这里必须返回true,不然后续监听不会收到事件,等同于在ACTION_DOWN中返回true
        //有一种写法是
        return e.actionMasked == MotionEvent.ACTION_DOWN
        //但大多数情况,直接返回true即可
        return true
    }

    //显示按下效果,忽略父布局是不是滑动布局的影响,用户触摸到并且触摸时间到了100ms显示按下效果,
    override fun onShowPress(e: MotionEvent?) {
    }

    //处理单击,(如果gesture支持长按,那么只有在长按时间500毫秒内抬起才会被调用)
    override fun onSingleTapUp(e: MotionEvent?): Boolean {
        //返回true代表消费了这个点击事件,该返回值用于给系统做记录,对事件序列不会产生影响
        return false
    }

    //处理滑动,接收到的事件序列是ACTION_MOVE,
    //distanceX 与 distanceY 是这次事件跟上次事件的触摸点的距离,数值是用旧的触摸点减去新的触摸点得到
    override fun onScroll(
        downEvent: MotionEvent,
        currentEvent: MotionEvent,
        distanceX: Float,
        distanceY: Float
    ): Boolean {
        return false
    }

    //长按
    override fun onLongPress(e: MotionEvent?) {
    }

    //快速滑动view后松手触发,处理快滑/惯性滑动后的后续操作,
    //velocityX velocityY 数值代表速率,单位时间内的位移
    override fun onFling(
        e1: MotionEvent?,
        e2: MotionEvent?,
        velocityX: Float,
        velocityY: Float
    ): Boolean {
        return false
    }

}

OnGestureListener方法粗解

1、onDown

view被按下的时候触发,返回true代表消费事件,(view的clickable要为true才能被响应)

onShowPress

显示按下效果,忽略父布局是不是滑动布局的影响,用户触摸到并且触摸时间到了100ms显示按下效果,

onSingleTapUp

处理单击,(如果gesture支持长按,那么只有在长按时间500毫秒内抬起才会被调用)

onScroll

处理滑动,接收到的事件序列是ACTION_MOVE,distanceX 与 distanceY 是这次事件跟上次事件的触摸点的距离,数值是用旧的触摸点减去新的触摸点得到

onFling

快滑后产生的惯性滑动效果,比如列表被快滑,手指已经松开了 但是列表还是会继续滑动一下 velocityX velocityY 数值代表速率,单位时间内的位移

onLongPress

被长按时回调 触发长按的时间是500ms

OnDoubleTapListener方法粗解

  • onSingleTapConfirmed 单击,在不是双击的时候触发,当支持双击的时候,使用该方法会比较准确,这里会确保不是双击
  • onDoubleTap 连续按下两次触发双击,按下抬起再次按下的时间间隔小于300ms会触发双击效果,有防抖效果(触发时间小于40ms也不会回调)
  • onDoubleTapEvent 双击后未松手的事件可以在该方法接收到,比如双击之后旋转view.

OnContextClickListener方法粗解

  • 等同于鼠标右键

SimpleOnGestureListener类粗解

public static class SimpleOnGestureListener implements OnGestureListener, OnDoubleTapListener,
        OnContextClickListener {

    public boolean onSingleTapUp(MotionEvent e) {
        return false;
    }

    public void onLongPress(MotionEvent e) {
    }

    public boolean onScroll(MotionEvent e1, MotionEvent e2,
            float distanceX, float distanceY) {
        return false;
    }

    public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
            float velocityY) {
        return false;
    }

    public void onShowPress(MotionEvent e) {
    }

    public boolean onDown(MotionEvent e) {
        return false;
    }

    public boolean onDoubleTap(MotionEvent e) {
        return false;
    }

    public boolean onDoubleTapEvent(MotionEvent e) {
        return false;
    }

    public boolean onSingleTapConfirmed(MotionEvent e) {
        return false;
    }

    public boolean onContextClick(MotionEvent e) {
        return false;
    }
}

当您只想收听所有手势的一个子集时,可以使用这个类。 这实现了OnGestureListenerOnDoubleTapListenerOnContextClickListener 中的所有方法, 不执行任何操作并返回false