在和手机屏幕进行交互的过程中,我们存在多种多样的手势,想比如单击,双击,滑动,两指的缩放,那么Android是怎么对我们的手势进行监听的呢?通过本篇文章的学习,你讲对Android手势处理有个大致的了解:
1.Android系统提供的手势监听器OnGestureListener
2.Android系统提供的手势监听器SimpleOnGestureListener
3.onTouchEvent自己去识别各种手势
一.手势监听器OnGestureListener
1.activity实现这个接口需要重写一下方法:
@Override
public boolean onDown(MotionEvent motionEvent) {
Log.i("lvv","手势--->onDown");
return false;
}
@Override
public void onShowPress(MotionEvent motionEvent) {
Log.i("lvv","手势--->onShowPress");
}
@Override
public boolean onSingleTapUp(MotionEvent motionEvent) {
Log.i("lvv","手势--->onSingleTapUp");
return false;
}
@Override
public boolean onScroll(MotionEvent motionEvent, MotionEvent motionEvent1, float v, float v1) {
Log.i("lvv","手势--->onScroll");
return false;
}
@Override
public void onLongPress(MotionEvent motionEvent) {
Log.i("lvv","手势--->onLongPress");
}
@Override
public boolean onFling(MotionEvent motionEvent, MotionEvent motionEvent1, float v, float v1) {
Log.i("lvv","手势--->onFling");
return true;
}
这些函数在什么时候会触发:
onDown(MotionEvent motionEvent):用户按下屏幕就会触发
onShowPress(MotionEvent motionEvent):如果是按下的时间超过瞬间,而且在按下的时候没有松开或者是拖动的,那么onShowPress就会执行,这个瞬间无法定义
onLongPress(MotionEvent e):长按触摸屏,超过一定时长,就会触发这个事件
onSingleTapUp(MotionEvent motionEvent):从名子也可以看出,一次单独的轻击抬起操作,也就是轻击一下屏幕,立刻抬起来,才会有这个触发,当然,如果除了Down以外还有其它操作,那就不再算是Single操作了,所以也就不会触发这个事件
onFling(MotionEvent motionEvent, MotionEvent motionEvent1, float v, float v1):滑屏,用户按下触摸屏、快速移动后松开,由1个MotionEvent ACTION_DOWN, 多个ACTION_MOVE, 1个ACTION_UP触发
onScroll(MotionEvent motionEvent, MotionEvent motionEvent1, float v, float v1):在屏幕上拖动事件
最后两个方法有点类似,四个参数的意义也一样:
motionEvent:第1个ACTION_DOWN MotionEvent
motionEvent1:最后一个ACTION_MOVE MotionEvent
v:X轴上的移动速度,像素/秒
v1:Y轴上的移动速度,像素/秒
2.创建手势类,并重写onTouchEvent方法,把onTouchEvent托管给手势类
//创建手势类并添加OnGestureListener监听器
GestureDetector gd=new GestureDetector(this,this);
//activity重写方法
@Override
public boolean onTouchEvent(MotionEvent event) {
return gd.onTouchEvent(event);//把onTouchEvent托管给手势类
}
滑动的时候会调用: onDown-----》onScroll----》onScroll----》onScroll----》………----->onFling
单击:onDown---》onSingleTapUp
双击:onDown---》onSingleTapUp---》onDown---》onSingleTapUp
二.手势监听器SimpleOnGestureListener
SimpleOnGestureListener手势监听器相比于OnGestureListener监听器的优点在于不需要重写所有方法,只需要关注自己想要点方法即可,而且它还包含了下面OnDoubleTapListener监听器单双击的方法,因此一般情况下用这个监听器最好:
//创建手势类添加监听器
GestureDetector gd=new GestureDetector(this,listener);
GestureDetector.SimpleOnGestureListener listener=new GestureDetector.SimpleOnGestureListener(){
@Override
public boolean onSingleTapConfirmed(MotionEvent e) {
return super.onSingleTapConfirmed(e);//单击
}
@Override
public boolean onDoubleTap(MotionEvent e) {
return super.onDoubleTap(e);//双击
}
@Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
return super.onFling(e1, e2, velocityX, velocityY);
}
};
同时,有一个OnDoubleTapListener是只需要关注单击和双击事件的:
//创建手势类添加监听器
GestureDetector gd=new GestureDetector(this,this);
gd.setOnDoubleTapListener(listener2);//手势类添加OnDoubleTapListener监听器
//activity重写方法
@Override
public boolean onTouchEvent(MotionEvent event) {
return gd.onTouchEvent(event);//把onTouchEvent托管给手势类
}
GestureDetector.OnDoubleTapListener listener2=new GestureDetector.OnDoubleTapListener() {
@Override
public boolean onSingleTapConfirmed(MotionEvent motionEvent) {
Log.i("lvv","手势---》onSingleTapConfirmed");//单击事件
return false;
}
@Override
public boolean onDoubleTap(MotionEvent motionEvent) {
Log.i("lvv","手势---》onDoubleTap");//双击事件
return true;
}
@Override
public boolean onDoubleTapEvent(MotionEvent motionEvent) {
Log.i("lvv","手势---》onDoubleTapEvent");
return false;
}
};
三.onTouchEvent自己识别
可以通过重写onTouchEvent方法获取event.getAction()得到手指的状态,按下,移动,抬起,判断是一根手指的时候就是拖动状态,可以用于模仿微信拖动图片拖动到下方然后消失,判断是两根手指的时候就是缩放状态,用于模仿微信双手缩放图片根据判断两根手指的距离是增加还是减少进行放大和缩小。
private int currentStatus=STATUS_INIT;//当前的状态
public static final int STATUS_INIT = 1;//初始化的状态
public static final int STATUS_ZOOM_OUT = 2;//图片放大状态常量
public static final int STATUS_ZOOM_IN = 3;//图片缩小状态常量
public static final int STATUS_MOVE = 4;//图片拖动状态常量
private float xMove = -1;//记录当前手指的横坐标
private float lastXMove = -1;//记录上次手指移动时的横坐标
private float yMove = -1;//记录当前手指的纵坐标
private float lastYMove = -1;//记录上次手指移动时的纵坐标
private double lastFingerDis;//记录上次两指之间的距离
private double fingerDis;//记录当前两指之间的距离
private float scaledRatio;//记录手指移动的距离所造成的缩放比例
@Override
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_POINTER_DOWN:
if (event.getPointerCount() == 2) {
// 当有两个手指按在屏幕上时,计算两指之间的距离
lastFingerDis = distanceBetweenFingers(event);
}
break;
case MotionEvent.ACTION_MOVE:
if (event.getPointerCount() == 1) {
// 只有单指按在屏幕上移动时,为拖动状态
xMove = event.getX();
yMove = event.getY();
if (lastXMove == -1 && lastYMove == -1) {
lastXMove = xMove;
lastYMove = yMove;
}
currentStatus = STATUS_MOVE;
// ------------拖动数值----------------
//after(xMove,yMove),befor(lastXMove,lastYMove)
lastXMove = xMove;
lastYMove = yMove;
} else if (event.getPointerCount() == 2) {
// 有两个手指按在屏幕上移动时,为缩放状态
fingerDis = distanceBetweenFingers(event);
if (fingerDis > lastFingerDis) {
currentStatus = STATUS_ZOOM_OUT;
} else {
currentStatus = STATUS_ZOOM_IN;
}
// ------------缩放倍数----------------
scaledRatio = (float) (fingerDis / lastFingerDis);
}
break;
case MotionEvent.ACTION_POINTER_UP:
if (event.getPointerCount() == 2) {
// 手指离开屏幕时将临时值还原
lastXMove = -1;
lastYMove = -1;
}
break;
case MotionEvent.ACTION_UP:
// 手指离开屏幕时将临时值还原
lastXMove = -1;
lastYMove = -1;
break;
default:
break;
}
return true;
}
/**
* 计算两个手指之间的距离。
*
* @param event
* @return 两个手指之间的距离
*/
private double distanceBetweenFingers(MotionEvent event) {
float disX = Math.abs(event.getX(0) - event.getX(1));
float disY = Math.abs(event.getY(0) - event.getY(1));
return Math.sqrt(disX * disX + disY * disY);
}
四.总结
以上就是关于Android手势处理的相关知识点,如有不足或者错误的地方请在下方指正。我们需要多看更需要多写,只有不断学习,不断进步才能不被淘汰。