GestureDetector用户手势识别的使用

当我们处理一些简单的点击,滑动事件的时候可以直接给View设置一个已经实现好的监听器。但是当我们进行一些复杂手势的识别以及处理的时候,系统已经实现好的监听器就不够用了,当然我们可以通过onTouch()中的MotionEvent的getAction获取当前用户手势所触发的事件, 如:ACTION_DOWN,ACTION_UP,ACTION_MOVE,也可以获取到当前手指点击的坐标,通过getX(),getY()进行获取。

        imageView.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View view, MotionEvent motionEvent) {
               int Action = motionEvent.getAction();
               switch (Action){
                    case MotionEvent.ACTION_DOWN:
                        Log.i("wk","手指按下");
                        break;
                    case MotionEvent.ACTION_MOVE:
                        Log.i("wk","手指移动"+"x坐标:"+ motionEvent.getX());
                        break;
                    case MotionEvent.ACTION_UP:
                        Log.i("wk","手指抬起");
                        break;
                }
                return false;
            }
        });

假设当我们需要识别用户的双击事件时,我们还得需要可以在onTouch()中进行书写相应的代码进行判断,因此遇到这种情况我们便可以使用谷歌给我们提供的GestureDetector类来检测用户的手势操作。

通过官方文档的描述可以知道GestureDetector类对外提供了两个接口和一个静态类

接口:OnGestureListener,OnDoubleTapListener 静态类:SimpleOnGestureListener

下面梳理一遍 实现OnGestureListener接口进行GestureDetector 手势识别的使用步骤:

1.首先创建OnGestureListener的监听函数:

创建一个类实现GestureDetector.OnGestureListener接口,实现方法

class MyGestureListener implements GestureDetector.OnGestureListener {

    }

2.创建 GestureDetector对象实例,传入上一步实现了GestureDetector.OnGestureListener接口类的实例:

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

3.设置需要进行手势监听的View的OnTouchListener的监听,重写onTouch()方法。



public class GestureDetectorActivity extends AppCompatActivity implements View.OnTouchListener {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_gesture_detector);
        //设置View的触摸监听,实现接口的方式实现
        imageView.setOnTouchListener(this);
    }

   imageView.setOnTouchListener(this);
   @Override
    public boolean onTouch(View view, MotionEvent motionEvent) {

        return mGestureDetector.onTouchEvent(motionEvent);

    }
}

4.在 onTouch()中,让GestureDetector接收处理触摸事件:

    @Override
    public boolean onTouch(View view, MotionEvent motionEvent) {

        return mGestureDetector.onTouchEvent(motionEvent);

    }

当将onTouch( )的触摸事件交给GestureDetector处理的时候,此时的GestureDetector类就可以进行手势监听了。

下面看一下 GestureDetector.OnGestureListener接口中需要实现的方法:


class MyGestureListener implements GestureDetector.OnGestureListener{
        //按下屏幕就会触发
        @Override
        public boolean onDown(MotionEvent motionEvent) {


            Log.i("wk", "==>onDown()");

            return false;
        }


        //如果是按下的时间超过瞬间,而且在按下的时候没有松开或者是拖动时触发
        @Override
        public void onShowPress(MotionEvent motionEvent) {

            Log.i("wk", "==>onShowPress()");

        }

        //轻击一下屏幕,立刻抬起来,才会有这个触发
        @Override
        public boolean onSingleTapUp(MotionEvent motionEvent) {


            Log.i("wk", "==>onSingleTapUp()");

            return false;
        }

        //在屏幕上拖动事件。无论是用手拖动view,或者是以抛的动作滚动,都会多次触发,这个方法

        @Override
        public boolean onScroll(MotionEvent motionEvent, MotionEvent motionEvent1, float distanceX, float distanceY) {

            Log.i("wk", "==>onScroll()");

            return false;
        }

        //长按触摸屏,超过一定时长,就会触发这个事件
        @Override
        public void onLongPress(MotionEvent motionEvent) {

            Log.i("wk", "==>onLongPress()");

        }


        //滑屏,用户按下触摸屏、快速移动后松开
        @Override
        public boolean onFling(MotionEvent motionEvent, MotionEvent motionEvent1, float v, float v1) {
            Log.i("wk", "==>onFling()");

            return false;
        }
}

这时开始郁闷了,为什么没有双击事件的监听呢?看前面我们知道GestureDetector类还提供了一个OnDoubleTapListener的接口,再同时实现这个接口,就可以实现双击的手势监听了。

    //双击事件相关的监听
        @Override
        public boolean onSingleTapConfirmed(MotionEvent motionEvent) {


            Log.i("wk", "==>onSingleTapConfirmed()");

            return false;
        }

        @Override
        public boolean onDoubleTap(MotionEvent motionEvent) {


            Log.i("wk", "==>onDoubleTap()");

            return false;


        }

        @Override
        public boolean onDoubleTapEvent(MotionEvent motionEvent) {


            Log.i("wk", "==>onDoubleTapEvent()");
            return false;
        }

也可以通过 GestureDetector.setOnDoubleTapListener()使用内部类的方式实现双击的监听:

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

        mGestureDetector.setOnDoubleTapListener(new GestureDetector.OnDoubleTapListener() {
          // 用来判定该次点击是SingleTap而不是DoubleTap,如果连续点击两次就是DoubleTap手势,如果只点击一次,系统等待一段时间后没有收到第二次点击则判定该次点击为SingleTap而不是DoubleTap,然后触发SingleTapConfirmed事件。
            @Override
            public boolean onSingleTapConfirmed(MotionEvent motionEvent) {
                return false;
            }

        //双击事件
            @Override
            public boolean onDoubleTap(MotionEvent motionEvent) {
                return false;
            }

        //双击间隔中发生的动作。指触发onDoubleTap以后,在双击之间发生的其它动作,包含down、up和move事件
            @Override
            public boolean onDoubleTapEvent(MotionEvent motionEvent) {
                return false;
            }
        });

GestureDetector.SimpleOnGestureListener 静态类的使用:

所有步骤与使用OnGestureListener实现接口的方式进行手势监听步骤一致,不同的是此处需要继承GestureDetector.SimpleOnGestureListener类实现手势的监听方法。相比实现接口的方式,使用继承的方式可以根据我们的需求实现用得到的方法,而不需要像实现接口那样将所有的方法全都重写。

下面用一个小例子来练习一下GestureDetector手势识别的使用:
(在ImageView上左右滑动实现图片的切换)

这里写图片描述

代码:

 //滑屏,用户按下触摸屏、快速移动后松开
        @Override
        public boolean onFling(MotionEvent motionEvent, MotionEvent motionEvent1, float v, float v1) {
            Log.i("wk", "==>onFling()");

            //手指按下的位置
            float downX = motionEvent.getX();
            float downY = motionEvent.getY();

            //手指抬起的位置
            float upX = motionEvent1.getX();
            float upY = motionEvent1.getY();

            float xDistance = downX - upX;
            float yDistance = downY - upY;

            Log.i("wk","downX:"+downX+"upX:"+upX);

            //判断当前手指滑动的方向,判断如果滑动的像素大于200并且是偏向水平方向时执行
            if(xDistance>0 && Math.abs(xDistance)>200 &&  Math.abs(xDistance)-Math.abs(yDistance)>0 ){

                Toast.makeText(GestureDetectorActivity.this,"右滑",Toast.LENGTH_SHORT).show();

                if(mIndex == Images.length-1){

                    Toast.makeText(GestureDetectorActivity.this,"已经滑动到最后一张图片了",Toast.LENGTH_SHORT).show();
                }else {

                    imageView.setImageResource(Images[mIndex]);

                    mIndex++;
                }


            }else if(xDistance<0 && Math.abs(xDistance)>200 && Math.abs(xDistance)-Math.abs(yDistance)>0) {


                Toast.makeText(GestureDetectorActivity.this,"左滑",Toast.LENGTH_SHORT).show();

                if(mIndex == 0){

                    Toast.makeText(GestureDetectorActivity.this,"已经滑动到第一张张图片了",Toast.LENGTH_SHORT).show();
                }else {

                    imageView.setImageResource(Images[mIndex]);

                    mIndex--;
                }
            }
            return false;
        }

上述例子比较简单,只需要根据手指按下的位置,以及抬起的位置判断滑动的方向即可。

眼睛酸涩………… 撒花~(≧▽≦)/~啦啦啦

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值