GestureDetector:手势检测

QuibblerQuibbler 2020-03-29 约 13 分钟 1863 次阅读

GestureDetector:手势检测

屏幕手势判断略复杂且都是重复工作,好在Android提供了通用的检测手势类GestureDetector,只需要将触摸事件MotionEvent传递给onTochEvent()方法,再由程序员自己实现对应监听方法的具体实现,GestureDetector会自动判断当前触摸手势类型:down,up,scroll,filing等。

1、监听接口

使用GestureDetector前需要先实现相应的接口,GestureDetector内部提供了几种接口OnGestureListener、OnContextClickListener、OnDoubleTapListener,以及一种简单的接口实现类:SimpleOnGestureListener,实现类前面三种接口。

1.1、OnGestureListener

最常用的接口,可以检测识别点击、按压、滑动、Fling、长按等手势。

public interface OnGestureListener {
        //用户按下屏幕
        boolean onDown(MotionEvent e);
        
        void onShowPress(MotionEvent e);
        
        //点击抬起事件,但是不能区分是否双击事件的抬起
        boolean onSingleTapUp(MotionEvent e);
        
        //手指滑动
        boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY);
        
        //用户长按后
        void onLongPress(MotionEvent e);
        
        //用户执行抛操作之后的回调,MOVE事件之后手松开(UP事件)那一瞬间的x或者y方向速度,达到一定数值(源码默认是每秒50px)
        boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY);
    }

1.2、OnContextClickListener

上下文单击时回调。

public interface OnContextClickListener {
        /**
         * Notified when a context click occurs.
         *
         * @param e The motion event that occurred during the context click.
         * @return true if the event is consumed, else false
         */
        boolean onContextClick(MotionEvent e);
    }

1.3、OnDoubleTapListener

用于通知何时双击或确认单击的监听器。

public interface OnDoubleTapListener {
        //单击事件
        boolean onSingleTapConfirmed(MotionEvent e);
        
        //双击事件
        boolean onDoubleTap(MotionEvent e);
        
        //双击间隔中发生的动作
        boolean onDoubleTapEvent(MotionEvent e);
    }

2、创建GestureDetector

查看源码可以看到GestureDetector有一下几种构造方法。

@Deprecated
    public GestureDetector(OnGestureListener listener, Handler handler) {
        this(null, listener, handler);
    }
    
    @Deprecated
    public GestureDetector(OnGestureListener listener) {
        this(null, listener, null);
    }

上面两个被标记为@Deprecated不建议使用,注意这两个方法都没有传入Context,内部调用的仍是下面的方法。

public GestureDetector(Context context, OnGestureListener listener) {
        this(context, listener, null);
    }
    
    /**
    *最终都是调用该方法初始化
    */
    public GestureDetector(Context context, OnGestureListener listener, Handler handler) {
        if (handler != null) {
            mHandler = new GestureHandler(handler);
        } else {
            mHandler = new GestureHandler();
        }
        mListener = listener;
        if (listener instanceof OnDoubleTapListener) {
            setOnDoubleTapListener((OnDoubleTapListener) listener);
        }
        if (listener instanceof OnContextClickListener) {
            setContextClickListener((OnContextClickListener) listener);
        }
        init(context);
    }

这里重点关注一下GestureDetector(Context context, OnGestureListener listener, Handler handler) 构造方法,可以看到传入的是OnGestureListener接口类型,但是另外两种接口的设置也在这里通过instanceof进行了判断,传入的对象是否同时实现了另外两种类型的接口,如有就调用方法设置对应的监听器。

当然也可以单独调用setOnDoubleTapListener()和setContextClickListener()方法设置其它两种监听器。

mListener = listener;
    if (listener instanceof OnDoubleTapListener) {
        setOnDoubleTapListener((OnDoubleTapListener) listener);
    }
    if (listener instanceof OnContextClickListener) {
        setContextClickListener((OnContextClickListener) listener);
    }

实现需要的回调接口,可以参考GestureDetector内部的静态示例类SimpleOnGestureListener。

private class Listener implements GestureDetector.OnGestureListener ,GestureDetector.OnContextClickListener{
        @Override
        public boolean onContextClick(MotionEvent e) {
            return false;
        }
        @Override
        public boolean onDown(MotionEvent e) {
            return false;
        }
        @Override
        public void onShowPress(MotionEvent e) {
        }
        @Override
        public boolean onSingleTapUp(MotionEvent e) {
            return false;
        }
        @Override
        public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
            return false;
        }
        @Override
        public void onLongPress(MotionEvent e) {
        }
        @Override
        public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
            return false;
        }
    }

初始化GestureDetector实例,这里Listener同时实现了OnGestureListener、OnContextClickListener接口,构造的时候都会设置对应的监听器。

GestureDetector mGestureDetector = new GestureDetector(this, new Listener());

3、使用GestureDetector

在View或Activity的onTouchEvent()方法中给GestureDetector传入触摸事件即可

@Override
    public boolean onTouchEvent(MotionEvent event) {
        return mGestureDetector.onTouchEvent(event);
    }

相关资料:

         Reference > GestureDetector">Android Developers > Reference > GestureDetector

         Reference > MotionEvent">Android Developers > Reference > MotionEvent

        GestureDetector.OnGestureListener

        看完这篇还不会 GestureDetector 手势检测,我跪搓衣板!

        

相关推荐

WilliamChart:轻量美观的 Android 图表库实战
精选开源

WilliamChart:轻量美观的 Android 图表库实战

WilliamChart:轻量美观的 Android 图表库实战数据可视化是运动、健康、金融、统计类 App 的刚需。MPAndroidChart 功能最全但偏重复杂,WilliamChart 走的则是"轻量 + 美观 + Kotlin 原生"路线——v3 用 Kotlin 完全重写,API 极简,一行 chart.animate(dataSet) 就能把数据画成带动画的折线/柱状/环形图,开箱即

175