您的当前位置:首页正文

Android GestureDetector手势识别

2024-11-30 来源:个人技术集锦

GestureDetectorCompat

在View与用户的交互处理中,通常可以采用重写View的onTouchEvent方法来判断处理手势的一些操作,这种方式需要开发者自己处理手势的一些数据判断,在简单的手势例如上下左右滑动之类容易处理,遇到一些复杂的手势操作就很难判断处理。Android的View包中给我们提供了GestureDetector手势处理类来帮助开发者来处理复杂的手势操作事件。

GestureDetector
是在API LEVEL1级别所提供的类,在SDK Version 22中引入了GestureDetectorCompat兼容类,也就是GestureDetector增加了对低版本的兼容性,所以现在已废弃GestureDetector,转而使用新版本的GestureDetectorCompat类。

public final class GestureDetectorCompat
extends Object

java.lang.Object
↳ android.support.v4.view.GestureDetectorCompat

GestureDetectorCompat类使用所提供的MotionEvents检测各种手势和事件。当一个特定的手势动作事件发生时,GestureDetector.OnGestureListener监听器回调会通知用户所发生的事件。这个类只能用于通过触摸屏幕所触发的MotionEvents事件。
框架的手势检测器的兼容性实现保证了在所有平台版本上,从Jellybean MR1版本骑更新的焦点滚动行为都可以运行。

GestureDetector类对外提供了两个接口::OnGestureListener,OnDoubleTapListener。

OnGestureListener手势监听器接口

 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);
        //快速滑动
        boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY);
    }

OnGestureListener 监听器接口中包含了6个方法,分别是:

  • onDown按下
    当手指向下点击屏幕时立即触发该事件,所有其他的手势事件都应该在该事件发生之后发生。
  • onShowPress按住
    当手指向下点击屏幕后,但是没有滑动或者抬起离开屏幕时触发。该事件跟onLongPress长按很像,但是触发的时间比onLongPress短,即长按屏幕时,onShowPress比onLongPress更早触发。这个事件通常被用来向用户提供可视化反馈,让他们知道他们的行为已经被识别,即突出一个元素。
  • onSingleTapUp抬起
    当手指抬起离开屏幕时触发该事件。
  • onScroll滚动
    当手指在屏幕上滑动时触发该事件,参数中提供了初始的按下事件和当前的移动事件的信息,同时还包括了X和Y的滚动距离。
  • onLongPress长按
    当手指按下屏幕后长时间不操作时触发该时间。
  • onFling快速滑动
    当手指在屏幕上点击,快速滑动,抬起离开屏幕时触发该事件,可以理解为抛掷操作。参数提供了两个MotionEvent,e1即在开始快速滑动时点击屏幕的事件,e2即
    触发当前onFling的移动动作事件。同时还提供了沿X和Y轴的速度,单位是每秒/像素点,velocityX在X轴上以每秒X像素的速度,velocityY在Y轴上以每秒Y像素的速度。
  • OnDoubleTapListener 双击监听器接口

     public interface OnDoubleTapListener {
            //确认单击
            boolean onSingleTapConfirmed(MotionEvent e);
            //双击
            boolean onDoubleTap(MotionEvent e);
            //双击
            boolean onDoubleTapEvent(MotionEvent e);
        }

    当双击或确认单击时触发该事件监听器。

  • onSingleTapConfirmed确认单击
    当单次点击时触发该事件。与onSingleTapUp(MotionEvent)方法不同的是,只有在手势检测器确定用户的第一次点击之后,但是在第二次点击形成双击之前触发该事件。
  • onDoubleTap双击
    当双击屏幕时触发该事件。
  • onDoubleTapEvent
    当双击屏幕的过程中其他手势发生时触发该事件,包括按下屏幕,在屏幕上移动和抬起离开屏幕。参数中的MotionEvent即在双击手势中发生的动作事件。
  • 使用很简单,只需要在自定义View中或者Activity,Fragment中实现GestureDetector.OnGestureListener接口,然后创建一个GestureDetectorCompat 实例,参数中第一个参数为Context,第二个参数为OnGestureListener接口,然后重写自定义View或者Activity,Fragment的onTouchEvent方法,在onTouchEvent方法中调用gestureDetector.onTouchEvent(event);来将触摸事件分发给GestureDetector手势监听器处理。

    public class MainActivity extends BaseActivity implements GestureDetector.OnGestureListener{
        private static final String DEBUG_TAG="Gestures";
        private GestureDetectorCompat gestureDetector;
    
        @Override
        protected void initView() {
            setContentView(R.layout.activity_main);
        }
    
        @Override
        protected void initData() {
            gestureDetector=new GestureDetectorCompat(this,this);
        }
    
        @Override
        protected void initListener() {
    
        }
    
        @Override
        public boolean onTouchEvent(MotionEvent event){
            return gestureDetector.onTouchEvent(event);
        }
    
        @Override
        public boolean onDown(MotionEvent e) {
            Log.d(DEBUG_TAG,"onDown:"+e.toString());
            return false;
        }
    
        @Override
        public void onShowPress(MotionEvent e) {
            Log.d(DEBUG_TAG,"onShowPress:"+e.toString());
        }
    
        @Override
        public boolean onSingleTapUp(MotionEvent e) {
            Log.d(DEBUG_TAG,"onSingleTapUp:"+e.toString());
            return false;
        }
    
        @Override
        public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
            Log.d(DEBUG_TAG,"onScroll:"+e1.toString()+"--"+e2.toString()+"--"+distanceX+"--"+distanceY);
            return false;
        }
    
        @Override
        public void onLongPress(MotionEvent e) {
            Log.d(DEBUG_TAG,"onLongPress:"+e.toString());
        }
    
        @Override
        public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
            Log.d(DEBUG_TAG,"onFling:"+e1.toString()+"=="+e2.toString()+"=="+velocityX+"=="+velocityY);
            return false;
        }
    }

    同时也可以在View的onTouchListener方法中处理作用在View上的手势:

    public class MainActivity extends BaseActivity {
        private static final String DEBUG_TAG="Gestures";
        private GestureDetectorCompat gestureDetector;
        private LinearLayout container;
    
        @Override
        protected void initView() {
            setContentView(R.layout.activity_main);
            container= (LinearLayout) findViewById(R.id.Container);
        }
    
        @Override
        protected void initData() {
            gestureDetector=new GestureDetectorCompat(this,new MyGestureListener());
        }
    
        @Override
        protected void initListener() {
            container.setOnTouchListener(new View.OnTouchListener() {
                @Override
                public boolean onTouch(View v, MotionEvent event) {
                    gestureDetector.onTouchEvent(event);
                    return false;
                }
            });
        }
    
        private class MyGestureListener extends GestureDetector.SimpleOnGestureListener{
            private static final String DEBUG_TAG="Gestures";
    
            @Override
            public boolean onDown(MotionEvent e) {
                Log.d(DEBUG_TAG,"onDown:"+e.toString());
                return false;
            }
    
            @Override
            public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
                Log.d(DEBUG_TAG,"onFling:"+e1.toString()+"=="+e2.toString()+"=="+velocityX+"=="+velocityY);
                return false;
            }
        }
    }

    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;
            }
        }

    SimpleOnGestureListener 是GestureDetector手势检测器里面的一个轻量级的静态内部类,实现了OnGestureListener, OnDoubleTapListener,OnContextClickListener所有接口方法,但全是空方法和返回false。这个静态内部类主要是方便开发者实现自己需要的监听器方法,当自己实现OnGestureListener接口时,需要实现全部6个监听器方法,其他很多时候并不是要处理所有的手势操作,但只需要处理其中的某几个手势监听方法时,可以继承SimpleOnGestureListener 实现一个子类,重写里面的某几个手势监听方法就可以达到相同的目的。

    如下代码只实现了onDown和onFling方法:

    public class MainActivity extends BaseActivity{
        private static final String DEBUG_TAG="Gestures";
        private GestureDetectorCompat gestureDetector;
    
        @Override
        protected void initView() {
            setContentView(R.layout.activity_main);
        }
    
        @Override
        protected void initData() {
            gestureDetector=new GestureDetectorCompat(this,new MyGestureListener());
        }
    
        @Override
        protected void initListener() {
    
        }
    
        @Override
        public boolean onTouchEvent(MotionEvent event){
            return gestureDetector.onTouchEvent(event);
        }
    
        private class MyGestureListener extends GestureDetector.SimpleOnGestureListener{
            private static final String DEBUG_TAG="Gestures";
    
            @Override
            public boolean onDown(MotionEvent e) {
                Log.d(DEBUG_TAG,"onDown:"+e.toString());
                return false;
            }
    
            @Override
            public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
                Log.d(DEBUG_TAG,"onFling:"+e1.toString()+"=="+e2.toString()+"=="+velocityX+"=="+velocityY);
                return false;
            }
        }
    }
显示全文