美文网首页UI
彻底理解Android手势开发GestureDecetor之使用

彻底理解Android手势开发GestureDecetor之使用

作者: 蜗牛猿猿 | 来源:发表于2018-08-26 21:45 被阅读3次

    人生和游戏一样,需要不断的打怪升级,等到了一定的等级,也就打开了新的天地!

    1、简介

    Android手势常见的有单击、双击、长按、滑动、快速滑动、上滑、下滑、左滑、右滑等等。
    我们一般重写View的onTouchEvent(MotionEvent event)然后做一些处理。基本的代码格式:

     @Override
        public boolean onTouchEvent(MotionEvent event) {
            int action = event.getActionMasked();
            switch (action) {
                case MotionEvent.ACTION_DOWN:
                    //逻辑处理
                    break;
                case MotionEvent.ACTION_MOVE:
                    //逻辑处理
                    break;
                case MotionEvent.ACTION_UP:
                    //逻辑处理
                    break;
                default:
                    break;
            }
            return true;
        }
    

    这一部分代码的处理基本是一致的。于是强大的谷歌提供了GestureDetector类来简化我们对手势的处理。
    下面我们来看看手势开发的API

    2、API介绍

    手势开发涉及的API

    • GestureDetector(手势管理器)
    • GestureDetector.OnGestureListener(接口,提供一些回调的手势方法)
    • GestureDetector.OnDoubleTapListener(接口,提供一些回调的手势方法)
    • GestureDetector.OnContextClickListener(接口,提供一些回调的手势方法)
    • GestureDetector.SimpleOnGestureListener(空实现了上面的三个手势接口,供开发者重写指定的手势方法)

    2.1、GestureDetector API

    手势追踪管理器

    • 构造方法
    public GestureDetector(Context context, OnGestureListener listener) 
    public GestureDetector(Context context, OnGestureListener listener, Handler handler) 
    public GestureDetector(Context context, OnGestureListener listener, Handler handler,
                boolean unused) 
    构造方法最终都走到了四个参数的构造方法。
    参数:context //上下文,基本都要传入的参数
    参数:OnGestureListener //传入一个手势回调接口
    参数:handler //可以改变内部handler的Looper,下一篇原理篇讲解
    参数:unused //这个参数目前源码中没有用到
    
    • 对外方法
    isLongpressEnabled() //是否支持长按手势
    setIsLongpressEnabled(boolean isLongpressEnabled)//设置是否允许长按操作
    setOnDoubleTapListener(OnDoubleTapListener onDoubleTapListener)//配置这个接口中支持的手势,下面可以看这个接口支持的手势方法
    setContextClickListener(OnContextClickListener onContextClickListener)//配置这个接口中支持的手势,下面可以看这个接口支持的手势方法
    onTouchEvent(MotionEvent ev)//核心方法,处理各种手势的逻辑在这个里面
    

    2.2、GestureDetector.OnGestureListener

    boolean onDown(MotionEvent e)// 用户按下触发,ACTION_DOWN事件,一次手势过程中触发一次
    void onShowPress(MotionEvent e)//用户按下但是没有发生move和up,给用户一个可视化的反馈方法,一次手势过程中触发一次
    onLongPress(MotionEvent e)//长按事件
    onSingleTapUp(MotionEvent e)//单击事件,这个事件发生了,可能会发生双击事件
    onFling(MotionEvent e1, MotionEvent e2, float velocityX,float velocityY) //快速滑动事件
    参数:e1:快速滑动第一个DOWN事件 e2:触发快速滑动的move时间 velocityX:快速滑动事件x方向的速度,单位是px/s,就是每秒划过了多少的像素 velocityY:y方向的速度和x含义一致。
    boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY)//滑动事件,滑动过程会频繁调用
    参数:e1:开始滑动第一个DOWN事件 e2:当前的滑动事件 distanceX:前后两次滑动事件x方向的变化值 distanceY:前后两次滑动事件y方向的变化值
    

    2.3、GestureDetector.OnDoubleTapListener

    boolean onSingleTapConfirmed(MotionEvent e)//严格的单击事件,这个事件发生了就不可能会发生双击事件
    boolean onDoubleTap(MotionEvent e)//双击事件
    boolean onDoubleTapEvent(MotionEvent e)//发生了双击事件,在双击期间ACTION_DOWN、ACTION_MOVE、ACTION_UP都会触发此回调
    

    2.4、GestureDetector.SimpleOnGestureListener

    对上面三个接口进行了空实现,手势监听推荐使用这个实现类,这样我们去重写我们需要的手势方法,就不需要每一个手势方法都重写了

    3、使用

    步骤:
    1、构建GestureDetector
    2、接管View的onTouchEvent事件处理
    

    示例:

    public class MyTestView extends AppCompatImageView {
    
        private static final String TAG = "MyTestView";
        private GestureDetector gestureDetector;
    
        public MyTestView(Context context) {
            super(context);
            init();
        }
    
        public MyTestView(Context context, AttributeSet attrs) {
            super(context, attrs);
            init();
        }
    
        public MyTestView(Context context, AttributeSet attrs, int defStyleAttr) {
            super(context, attrs, defStyleAttr);
            init();
        }
    
        private void init() {
            //1、构建GestureDetector对象,传入需要回调的手势接口,这里我们传入手势接口实现类SimpleOnGestureListener
            gestureDetector = new GestureDetector(getContext(), new GestureDetector.SimpleOnGestureListener() {
    
                @Override
                public boolean onDown(MotionEvent e) {
                    Log.d(TAG, "onDown()");
                    //此处必须返回true,否则就只能触发这个事件和onLongPress()事件了
                    //其他的事件都不会触发了,这个和android的事件分发机制有关,后面会写一篇关于事件分发。
                    return true;
                }
    
                @Override
                public void onLongPress(MotionEvent e) {
                    super.onLongPress(e);
                    Log.d(TAG, "onLongPress()");
                }
    
                @Override
                public boolean onSingleTapUp(MotionEvent e) {
                    Log.d(TAG, "onSingleTapUp()");
                    return super.onSingleTapUp(e);
                }
    
                @Override
                public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
                    Log.d(TAG, "onScroll() distanceX:" + distanceX + ",distanceY:" + distanceY);
                    ViewGroup viewGroup = (ViewGroup) getParent();
                    viewGroup.scrollBy((int) distanceX, (int) distanceY);
                    return true;
                }
    
                @Override
                public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
                    Log.d(TAG, "onFling()");
                    return super.onFling(e1, e2, velocityX, velocityY);
                }
    
            });
        }
    
        @Override
        public boolean onTouchEvent(MotionEvent event) {
            //2、调用gestureDetector.onTouchEvent(event)来接管view的onTouchEvent
            return gestureDetector.onTouchEvent(event);
        }
    }
    

    4、手势开发注意点

    • 手势方法中凡是有返回值的方法,这些方法的结果都会返回到view的onTouchEvent方法中,有些方法会影响view的事件分发。
    • onDown方法要返回true,否则就只能触发onDown和onLongPress事件了,其他的都触发不了了,原因就是影响了事件分发过程。
    • onSingleTapUp和onSingleTapConfirmed的区别:
      都理解是单击事件,onSingleTapUp事件发生了,后面还是可能会触发onDoubleTap双击事件;而onSingleTapConfirmed发生就是严格的单击事件后面不会发生onDoubleTap了。所以对于严格的单击事件应该重写onSingleTapConfirmed方法

    相关文章

      网友评论

        本文标题:彻底理解Android手势开发GestureDecetor之使用

        本文链接:https://www.haomeiwen.com/subject/aftaiftx.html