Android中的手势识别器GestureDetector
在Android中当按下屏幕滑动一段距离再抬起时会有MotionEvent的1个ACTION_DOWN,多个ACTION_MOVE和1个ACTION_UP被触发。当我们想监测在屏幕上的操作情况时我们就可以使用手势识别器。
手势识别器系统已经给我们实现好了使用起来非常简单,直接上code,代码说明都在代码注释里面。
public class MyView extends View implements OnGestureListener, OnTouchListener {
private static final String TAG = "Havorld";
private GestureDetector gestureDetector;
private Context context;
public MyView(Context context, AttributeSet attrs) {
super(context, attrs);
this.context = context;
initGestureDetector();
}
private void initGestureDetector() {
this.setLongClickable(true); // 必须设置,不然双击不生效
this.setOnTouchListener(this);
// 设置手势识别器方法一:
// gestureDetector = new GestureDetector(context,this);
// 设置手势识别器方法二(可以识别双击,SimpleOnGestureListener类继承了OnGestureListener和OnDoubleTapListener接口):
gestureDetector = new GestureDetector(context,
new SimpleOnGestureListener() {
// 双击
@Override
public boolean onDoubleTap(MotionEvent e) {
Log.e(TAG, "onDoubleTap");
return super.onDoubleTap(e);
}
// 双击事件的ACTION_DOWN,ACTION_MOVE,ACTION_UP都会触发该事件
@Override
public boolean onDoubleTapEvent(MotionEvent e) {
Log.e(TAG, "onDoubleTapEvent");
return super.onDoubleTapEvent(e);
}
// onDown之后没有滑动(onScroll)又没有长按(onLongPress)又没有双击,然后onSingleTapUp后触发
@Override
public boolean onSingleTapConfirmed(MotionEvent e) {
Log.e(TAG, "onSingleTapConfirmed");
return super.onSingleTapConfirmed(e);
}
// 按下事件
@Override
public boolean onDown(MotionEvent e) {
Log.e(TAG, "onDown");
return true;
}
// 按下还未松开
@Override
public void onShowPress(MotionEvent e) {
Log.e(TAG, "onShowPress");
}
// 按下后的抬起事件
@Override
public boolean onSingleTapUp(MotionEvent e) {
Log.e(TAG, "onSingleTapUp");
return false;
}
// 滑动事件
@Override
public boolean onScroll(MotionEvent e1, MotionEvent e2,
float distanceX, float distanceY) {
Log.e(TAG, "onScroll");
return false;
}
// 长按事件
@Override
public void onLongPress(MotionEvent e) {
Log.e(TAG, "onLongPress");
}
/*
* 用户按下触摸屏、快速移动后松开,由1个MotionEvent ACTION_DOWN,多个ACTION_MOVE,
* 1个ACTION_UP触发。 Fling事件的处理代码:
* 除了第一个触发Fling的ACTION_DOWN和最后一个ACTION_MOVE中包含的坐标等信息外
* ,我们还可以根据用户在X轴或者Y轴上的移动速度作为条件
* 比如下面的代码中我们就在用户移动超过50个像素,且X轴上每秒的移动速度大于100像素时才进行处理。
*
* @param e1 第1个ACTION_DOWN MotionEvent
*
* @param e2 最后一个ACTION_MOVE MotionEvent
*
* @param velocityX X轴上的移动速度,像素/秒
*
* @param velocityY Y轴上的移动速度,像素/秒
*/
@Override
public boolean onFling(MotionEvent e1, MotionEvent e2,
float velocityX, float velocityY) {
Log.e(TAG, "onFling");
// 触发条件 :
// X轴的坐标位移大于FLING_MIN_DISTANCE,且移动速度大于FLING_MIN_VELOCITY个像素/秒
final int FLING_MIN_DISTANCE = 50, FLING_MIN_VELOCITY = 100;
if (e1.getX() - e2.getX() > FLING_MIN_DISTANCE
&& Math.abs(velocityX) > FLING_MIN_VELOCITY) {
// 向左滑动
Log.e(TAG, "Fling left");
Toast.makeText(context, "Fling Left",
Toast.LENGTH_SHORT).show();
} else if (e2.getX() - e1.getX() > FLING_MIN_DISTANCE
&& Math.abs(velocityX) > FLING_MIN_VELOCITY) {
// 向右滑动
Log.e(TAG, "Fling right");
Toast.makeText(context, "Fling Right",
Toast.LENGTH_SHORT).show();
}
return true;
}
});
}
// 当手触摸到屏幕的时候最先触发此方法,然后将触摸事件交给手势识别器
@Override
public boolean onTouch(View v, MotionEvent event) {
return gestureDetector.onTouchEvent(event);
}
// @Override
// public boolean onTouchEvent(MotionEvent event) {
//
// //在onTouchEvent中把触摸事件交给手势识别器时不能触发双击事件
// boolean onTouchEvent = gestureDetector.onTouchEvent(event);
// return onTouchEvent;
// }
//
// 按下事件
@Override
public boolean onDown(MotionEvent e) {
Log.e(TAG, "onDown");
return true;
}
// 按下还未松开
@Override
public void onShowPress(MotionEvent e) {
Log.e(TAG, "onShowPress");
}
// 按下后的抬起事件
@Override
public boolean onSingleTapUp(MotionEvent e) {
Log.e(TAG, "onSingleTapUp");
return false;
}
// 滑动事件
@Override
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX,
float distanceY) {
Log.e(TAG, "onScroll");
return false;
}
// 长按事件
@Override
public void onLongPress(MotionEvent e) {
Log.e(TAG, "onLongPress");
}
// 快速滑动后松开事件
@Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
float velocityY) {
Log.e(TAG, "onFling");
return false;
}
}
在Activity布局里面直接引用这个自定义View就可以了