美文网首页Android自定义View
Android 滑动与手势GestureDetector

Android 滑动与手势GestureDetector

作者: 安安zoe | 来源:发表于2017-11-07 21:25 被阅读700次

onTouch 事件

  • 触摸事件接口:onTouchListener内部接口,可以通过重写它的onTouch(View v,MotionEvent event)方法,来处理一些Touch事件
  • 简单的Touch事件:
    1. ACTION_DOWN
    2. ACTION_MOVE
    3. ACTION_UP
    4. ACTION_CANCEL
    5. ACTION_OUTSIDE

GestureDetector

1. 手势识别GestureDetector

  • 方便开发人员处理屏幕上的触摸,拖动,单双击,滑动等提供的一组接口,用这个可以很方便在屏幕上做出想要的效果,比如滑动翻页,触摸不同区域采用不同处理等相对复杂的手势

2. GestureDetector类

  • 对外提供了两个接口(OnGestureListener)(OnDoubleTapListener)和一个类(SimpleOnGestureListener),第一个接口主要处理与触摸相关的事件,第二个接口主要处理与双击相关的事件,外部类是static class,它集成了上两个接口中功能,包含并重写了接口中的函数,但是方法体都是为空的,我们可以在外部继承这个类。好处在于使用上面的接口时,我们必须实现所有接口需要实现的方法,但是继承类的时候,我们可以重写我们需要重写的手势处理方法

3. OnGestureListener

  • 要重写的方法:
private class Mygesturelistener implements GestureDetector.OnGestureListener{  
    
    // 用户按下屏幕触发
    @Override
    public boolean onDown(MotionEvent e) {  
        // TODO Auto-generated method stub  
        return false;  
    }  
  
    @Override
    public void onShowPress(MotionEvent e) {  
        // TODO Auto-generated method stub  
          
    }  
  
    // 点击轻抬起
    // 非常快的Touchup:onDown- onSingleTapUp -onSingleTapConfirmed
    // 稍微慢的Touchup:onDown - onShowPress - onSingleTapUp- onSingleTapConfirmed
    @Override
    public boolean onSingleTapUp(MotionEvent e) {  
        // TODO Auto-generated method stub  
        return false;  
    }  
    
    // 在屏幕上滑动或者拖动事件
    // 滑屏事件: onDown-----》onScroll----》onScroll----》onScroll----》………----->onFling
    // 拖动:onDown------》onScroll----》onScroll------》(onFling)(可能产生)---》ACTION_UP
    @Override
    public boolean onScroll(MotionEvent e1, MotionEvent e2,  
            float distanceX, float distanceY) {  
        // TODO Auto-generated method stub  
        return false;  
    }  
  
    // 长按屏幕 触发顺序:
    // onDown - onShowPress(按下时间超过短暂的时间) - onLongPress
    @Override
    public void onLongPress(MotionEvent e) {  
        // TODO Auto-generated method stub  
          
    }  
  
    // 滑屏 也叫作抛掷
    // 滑屏之前必定触发onScroll,但是onScroll不一定会触发onFling
    @Override
    public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,  
            float velocityY) {  
        // TODO Auto-generated method stub  
        return false;  
    }       
}  
  • 注意onScroll和onFling这个问题,在网上查阅资料的时候发现有些人写错了,onFling作为滑动屏幕或者说抛掷这个动作有一点特殊,如果滑动过程中离开屏幕比较快,那么有可能会触发,但是onScroll动作结束后是不一定会触发onFling的,所以有时候我们需要检测onScroll动作结束时,需要再想办法,解决方案是:

onScroll 动作结束后,抬起时的ACTION_UP 并没有被消耗掉,可以捕捉这一个MotionEvent进行相应的操作。

4. OnDoubleTapListener

  • 双击监听
  • 注意:要想使用OnDoubleTapListener的几个函数,就必须先实现OnGestureListener
  • 使用方式1:创建一个类实现OnGestureListener 和 OnDoubleTapListener
  • 使用方式2:GestureDetector使用 setOnDoubleTapListener
  • 三个需要重写的方法
private class doubleTapListener implements GestureDetector.OnDoubleTapListener{  
  
    public boolean onSingleTapConfirmed(MotionEvent e) {  
        // TODO Auto-generated method stub  
        return false;  
    }  
  
    public boolean onDoubleTap(MotionEvent e) {  
        // TODO Auto-generated method stub  
        return false;  
    }  
  
    public boolean onDoubleTapEvent(MotionEvent e) {  
        // TODO Auto-generated method stub  
        return false;  
    }  

5. SimpleOnGestureListener

  • 这个其实不用细说,因为之前说过了包含并重写了接口中的函数,但是方法体都是为空的,我们可以在外部继承这个类。好处在于使用上面的接口时,我们必须实现所有接口需要实现的方法,但是继承类的时候,我们可以重写我们需要重写的手势处理方法

6. 使用

  • 创建GestureDetector,通过接口对象或者类来实例化
GestureDetector gestureDetector=new GestureDetector(GestureDetector.OnGestureListener listener);  

GestureDetector gestureDetector=new GestureDetector(Context context,GestureDetector.OnGestureListener listener);  
GestureDetector gestureDetector=new GestureDetector(Context context,GestureDetector.SimpleOnGestureListener listener);  
  • 对于接口实现,可以构造实例,也可以自定义类,注意对于前两个接口是implements,而SimpleOnGestureListener类需要extends

  • 绑定控件并在onTouchEvent中拦截

TextView v = findViewById(R.id.textview);
v.setOnTouchListener(this);
v.setClickable(true); //需要设置
v.setLongClickable(true);// 需要设置

public boolean onTouch(View v,MotionEvent event){
  return mGestureDetector.onTouchEvent(event);
}

手势运动方向判断

1. GestureDetector.OnGestureListener类的onScroll方法参数 distanceX 和 distanceY问题

参数 含义
e1 The first down motion event that started the scrolling
e2 The move motion event that triggered the current onScroll.he move motion event that triggered the current onScroll.
distanceX The distance along the X axis that has been scrolled since the last call to onScroll. This is NOT the distance between e1 and e2.
distanceY The distance along the Y axis that has been scrolled since the last call to onScroll. This is NOT the distance between e1 and e2.
  • 注意理解:e1 是滑动起点时的Motionevent,e2 是滑动过程中不断产生的Motionevent,要注意的是onScroll在滑动过程是不断调用的,注意这个FIRST,是指在手指头没有抬起来结束整个滑动动作前,e1是保持不变的,但是e2是一直在变化着的,所以Distancex和DistanceY也是不断变化着的,是两次调用onScroll之间x之间的距离,因此需要注意的是滑动刚开始时的第一个DistanceX是不具有参考性的。
  • 手指滑动的方向可以根据 e1.getX(),e1.getY(),e2.getX(),e2.getY(),DistanceX,DistanceY参考得到,精确一点可以根据DistanceX,DistanceY求出滑动轨迹的斜率,但是同样要注意的是第一个Distance需要商榷一下。

参考:

  1. 用户手势检测-GestureDetector使用详解

相关文章

网友评论

    本文标题:Android 滑动与手势GestureDetector

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