Android 滑动与手势GestureDetector
2017-11-07 本文已影响700人
安安zoe
onTouch 事件
- 触摸事件接口:onTouchListener内部接口,可以通过重写它的onTouch(View v,MotionEvent event)方法,来处理一些Touch事件
- 简单的Touch事件:
- ACTION_DOWN
- ACTION_MOVE
- ACTION_UP
- ACTION_CANCEL
- 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需要商榷一下。