Android手势使用之 GestureDetector


Android中对触摸事件的处理使用的是onTouchEvent,如果你对这块只是还不是很熟练,请查看我的另一篇文章:

android触摸事件处理逻辑

如果要在处理监听里面自己去写手势处理不是不可以,只是非常的麻烦,你自己要判断各种坐标值,点击时间等等,好在Google给我们已经封装好了一个手势处理类:GestureDetector,使用这个类就可以非常方便的处理单击、双击等各种手势,与手势相关的类有:

GestureDetector.OnDoubleTapListener:GestureDetector的内部接口,用来处理双击情况。

GestureDetector.OnGestureListener:GestureDetector的内部接口,用来处理单击情况。

GestureDetector.SimpleOnGestureListener:GestureDetector的内部类,实现了上面两个接口,不过只是空实现。


给一个View处理手势事件,一般要按照下面的步骤操作(这里我以ImageView为例,所有的view都一样):
1、根据自己的需求创建上面3个类中的一个对象。

2、创建一个GestureDetector对象,参数传入第一步的对象。

3、给View设置onTouchListener监听,在return语句写上gestureDetector.onTouchEvent(event)。

4、给View设置:imgv.setClickable(true)、imgv.setFocusable(true)、imgv.setLongClickable(true),这一步非常重要,不然出不来效果!

是的,就是这里简单,我们的大部分逻辑是要在第一步完成,可能你对第一步的“根据自己的需求创建上面3个类中的一个对象”这句话不是很明白,我的意思是:如果你只需要监听单击的情况,那么你只需要得到实现了onGestureListener接口的对象,如果是双击情况,就只需要得到实现了onDoubleTapListener接口的对象,如果两种情况你都需要考虑,那么你可以得到一个simpleOnGestureListener对象或者一个实现了上面两个接口的对象。我们来分别看看这些类里面有哪些方法:

GestureDetector.OnDoubleTapListener:

  GestureDetector.OnDoubleTapListener doubleTapListener = new GestureDetector.OnDoubleTapListener() {
            //单击的情况
            @Override
            public boolean onSingleTapConfirmed(MotionEvent e) {
                Log.e(TAG, "onSingleTapConfirmed:" + System.currentTimeMillis());
                return false;
            }

            //双击
            @Override
            public boolean onDoubleTap(MotionEvent e) {
                Log.e(TAG, "onDoubleTap:" + System.currentTimeMillis());
                return false;
            }

            //双击包含多个actionmove事件
            @Override
            public boolean onDoubleTapEvent(MotionEvent e) {
                Log.e(TAG, "onDoubleTapEvent:" + System.currentTimeMillis());
                return false;
            }
        };
GestureDetector.OnGestureListener:

  //单击手势
        GestureDetector.OnGestureListener gestureListener = new GestureDetector.OnGestureListener() {
            //手机一触摸立即触发
            @Override
            public boolean onDown(MotionEvent e) {
                Log.e(TAG, "onDown:" + System.currentTimeMillis());
                return false;
            }

            //手指触摸事件超过半秒触发
            @Override
            public void onShowPress(MotionEvent e) {
                Log.e(TAG, "onShowPress:" + System.currentTimeMillis());
            }

            //触摸立即弹起触发
            @Override
            public boolean onSingleTapUp(MotionEvent e) {
                Log.e(TAG, "onSingleTapUp:" + System.currentTimeMillis());
                return false;
            }

            //触摸滑动
            @Override
            public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
                Log.e(TAG, "onScroll:" + System.currentTimeMillis());
                return false;
            }

            //触摸超过2秒
            @Override
            public void onLongPress(MotionEvent e) {
                Log.e(TAG, "onLongPress:" + System.currentTimeMillis());
            }

            //触摸不抬起,迅速滑动
            @Override
            public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
                Log.e(TAG, "onFling:" + System.currentTimeMillis());
                return false;
            }
        };
GestureDetector.SimpleOnGestureListener:这个类除了实现了上面两个接口,还实现了一个接口OnContextClickListener,因为他是空实现,所以里面的方法基本就是接口的方法,故没有什么好说的。

下面用一个小demo来演示如何使用手势,demo里面的view使用的是imageView,接口使用匿名内部类的形式。

首先来看Activity里面的代码

public class MainActivity extends Activity {
    private ImageView imgv;
    private String TAG = "MainActivity";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        imgv = (ImageView) findViewById(R.id.imgv);
        //单击手势
        GestureDetector.OnGestureListener gestureListener = new GestureDetector.OnGestureListener() {
            //手机一触摸立即触发
            @Override
            public boolean onDown(MotionEvent e) {
                Log.e(TAG, "onDown:" + System.currentTimeMillis());
                return false;
            }

            //手指触摸事件超过半秒触发
            @Override
            public void onShowPress(MotionEvent e) {
                Log.e(TAG, "onShowPress:" + System.currentTimeMillis());
            }

            //触摸立即弹起触发
            @Override
            public boolean onSingleTapUp(MotionEvent e) {
                Log.e(TAG, "onSingleTapUp:" + System.currentTimeMillis());
                return false;
            }

            //触摸滑动
            @Override
            public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
                Log.e(TAG, "onScroll:" + System.currentTimeMillis());
                return false;
            }

            //触摸超过2秒
            @Override
            public void onLongPress(MotionEvent e) {
                Log.e(TAG, "onLongPress:" + System.currentTimeMillis());
            }

            //触摸不抬起,迅速滑动
            @Override
            public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
                Log.e(TAG, "onFling:" + System.currentTimeMillis());
                return false;
            }
        };
        //双击手势
        GestureDetector.OnDoubleTapListener doubleTapListener = new GestureDetector.OnDoubleTapListener() {
            //单击的情况
            @Override
            public boolean onSingleTapConfirmed(MotionEvent e) {
                Log.e(TAG, "onSingleTapConfirmed:" + System.currentTimeMillis());
                return false;
            }

            //双击
            @Override
            public boolean onDoubleTap(MotionEvent e) {
                Log.e(TAG, "onDoubleTap:" + System.currentTimeMillis());
                return false;
            }

            //双击包含多个actionmove事件
            @Override
            public boolean onDoubleTapEvent(MotionEvent e) {
                Log.e(TAG, "onDoubleTapEvent:" + System.currentTimeMillis());
                return false;
            }
        };


        //创建手势对象,并且设置手势监听
        final GestureDetector gestureDetector = new GestureDetector(MainActivity.this, gestureListener);
        //给gestrue设置双击手势监听
        gestureDetector.setOnDoubleTapListener(doubleTapListener);
        //给Imageview设置触摸监听,在return的时候把事件传递给gesture
        imgv.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                return gestureDetector.onTouchEvent(event);
            }
        });
        //这几步一定要写,不然出不来效果
        imgv.setClickable(true);
        imgv.setFocusable(true);
        imgv.setLongClickable(true);
    }
}

ok,Activity里面布局文件就一个imageView,给这个imageview设置onTouchListener监听,监听里面把触摸事件传给gestureDetector,gestureDetector设置了双击监听,在每一个方法里面如果执行了就打印一个log,日志带执行时间,下面就来对这个demo做测试。

点击图片迅速抬起:


点击图片等待半秒抬起:


点击图片不松开,超过一秒松开:


双击图片:


点击图片,滑动:


扫描关注我的微信公众号:



最后附上Demo(android studio开发):下载



  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值