GestureDetector:手势检测

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

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 手势检测,我跪搓衣板!

        

相关推荐

精选
ViewPager和PagerAdapter、FragmentPagerAdapter、FragmentStatePager
Android

ViewPager和PagerAdapter、FragmentPagerAdapter、FragmentStatePager

ViewPager1、ViewPagerandroidx.viewpager.widget.ViewPager,Android中使用非常广泛的控件,可以说是APP必备:首次打开引导页、页面Banner广告等。常用方法:setAdapter() 设置适配器setOffscreenPageLimit() 设置缓存的页面个数,默认是 1setCurrentItem() 跳转到特定的页面setOnPage

1.1k
获取Android内置WebView内核版本
Android

获取Android内置WebView内核版本

获取Android内置WebView内核版本竟然能遇到这样奇葩的事情,网页用的技术过于新颖,以至于只支持高版本Chromium内核的,低版本安卓系统中内置的内核版本较低,无法加载前端页面。1、设置查看在系统设置里 > 应用 > 应用管理 > 显示系统应用,查看WebView组件:2、页面查看通过WebView发起的网络请求,都会带上浏览器的UA,通常页面都可以通过UA判断浏览器的内核版本。这里有两

1.1w
Android 14适配总结
Android

Android 14适配总结

Android 14适配总结毕业工作至今已经适配了三个Android大版本,从Android 11到Android 12、再到Android 13。2023年,Google即将推出的Android 14,上半年已经开始第一批适配。现在,第四个Android版本已经适配完,总结记录一下。1、Android 14计划Google一般会在2月份对外发布预告,同时放出开发者预览版。“拉通”各大平台、厂商以

1.1w