Android View之GestureDetector

(一)GestureDetector 概述

GestureDetector:主要用来结合MotionEvent检测并识别各种手势事件,注意它只能用来识别并接管触摸事件的MotionEvent。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
/********  常用步骤  **********/

// 1、创建GestureDetector实例并实现监听。注意:这里只会有一种事件类型的回调触发。
GestureDetector gestureDetector = new GestureDetector(this, new GestureDetector.SimpleOnGestureListener() {
@Override
public boolean onSingleTapConfirmed(MotionEvent e) {
Toast.makeText(MainActivity.this, "单击确认(事件),双击发生时不会触发", Toast.LENGTH_SHORT).show();
return false;
}

@Override
public boolean onDoubleTap(MotionEvent e) {
Toast.makeText(MainActivity.this, "双击事件", Toast.LENGTH_SHORT).show();
return super.onDoubleTap(e);
}

@Override
public void onLongPress(MotionEvent e) {
super.onLongPress(e);
Toast.makeText(MainActivity.this, "长按事件", Toast.LENGTH_SHORT).show();
}

@Override
public boolean onDoubleTapEvent(MotionEvent e) {
switch (e.getActionMasked()) {
case MotionEvent.ACTION_UP:
Toast.makeText(MainActivity.this, "双击事件(手指抬起)", Toast.LENGTH_SHORT).show();
break;
}
return super.onDoubleTapEvent(e);
}

});

// 2、为指定控件设置触摸监听并让GestureDetector接管onTouchEvent事件。注意:view1需要是可点击的
view1.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
return mGestureDetector.onTouchEvent(event);
}
});

(二)GestureDetector 方法

1
2
3
4
5
// 设置是否禁用长按事件
mGestureDetector.setIsLongpressEnabled(false);

// 是否允许长按事件
mGestureDetector.isLongpressEnabled();

(三)GestureDetector 实例

1、GestureDetector 手势检测

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
// 默认监听OnGestureListener。常用的是SimpleOnGestureListener
private GestureDetector.OnGestureListener mDefaultGestureListener = new GestureDetector.OnGestureListener() {

/**
* 当View为文本、图片默认不可点击时,为保证事件被唯一的 View 消费,
* 要么声明它们的 clickable 为 true,要么onDown回 true。
* @param e 手指按下时的MotionEvent
* @return true则被唯一的View消费,反之被可被多个View消费
*/
@Override
public boolean onDown(MotionEvent e) {
DebugLog.e("按下");
return true;
}

/**
* 按下超过100ms触发,若小于100ms或事件被立即拦截则不会被触发。
* @param e 手指按下时的MotionEvent
*/
@Override
public void onShowPress(MotionEvent e) {
DebugLog.e("onShowPress");
}

/**
* 单击抬起(在双击的第一次抬起时触发)
* @param e 手指按下时的MotionEvent
*/
@Override
public boolean onSingleTapUp(MotionEvent e) {
DebugLog.e("onSingleTapUp");
return false;
}

/**
* 监听滚动
* @param e1 手指按下时的MotionEvent
* @param e2 手指移动时的MotionEvent
* @param distanceX 在 X 轴上滚动的距离
* @param distanceY 在 Y 轴上滚动的距离
*/
@Override
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
DebugLog.e("onScroll#distanceX:" + distanceX + ",distanceY:" + distanceY);
return false;
}

/**
* 长按超过500ms触发
* @param e 手指按下时的MotionEvent
*/
@Override
public void onLongPress(MotionEvent e) {
DebugLog.e("onLongPress");
}

/**
* 抛(投掷)。通过 e1 和 e2 获取到手指按下和抬起时的坐标、时间等。
* 通过 velocityX 和 velocityY 获取到在这段时间内的运动速度,单位是像素(距离)/秒。
* @param e1 手指按下时的MotionEvent
* @param e2 手指移动时的MotionEvent
* @param velocityX 在 X 轴上的运动速度(像素/秒)。
* @param velocityY 在 Y 轴上的运动速度(像素/秒)。
*/
@Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
DebugLog.e("onScroll#velocityX:" + velocityX + ",velocityY:" + velocityY);
return false;
}
};

2、ScaleGestureDetector 缩放手势检测

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
/**
* View之ScaleGestureDetector - 缩放手指检测(至少2根手指)
*
* @author [*昨日重现*] lhy_ycu@163.com
* @since version 1.0
*/
public class ScaleGestureDetectorView extends View {

private ScaleGestureDetector mScaleGestureDetector;
private int mPointCount;// 手指数量

public ScaleGestureDetectorView(Context context) {
this(context, null);
}

public ScaleGestureDetectorView(Context context, AttributeSet attrs) {
super(context, attrs);
init(context);
}

private void init(Context context) {
mScaleGestureDetector = new ScaleGestureDetector(context, new ScaleGestureDetector.OnScaleGestureListener() {

/**
* 缩放手势被触发
*
* @param detector 缩放手势
* @return true:表示当前缩放事件已被处理,会重新积累缩放因子;false 则会继续积累缩放因子。
*/
@Override
public boolean onScale(ScaleGestureDetector detector) {
DebugLog.e("focus(" + detector.getFocusX() + "," + detector.getFocusY() + ")"); // 缩放中心(x,y)坐标 -- 焦点
DebugLog.e("scale = " + detector.getScaleFactor()); // 缩放因子 -- 比例
DebugLog.e("mPointCount:" + mPointCount);
return false;
}

/**
* 缩放手势开始
*
* @param detector 缩放手势
* @return 只有返回true才可使用缩放手势
*/
@Override
public boolean onScaleBegin(ScaleGestureDetector detector) {
DebugLog.e("-----缩放手势开始-----");
return true;
}

/**
* 缩放手势结束 MotionEvent.ACTION_POINTER_UP时触发
*
* @param detector 缩放手势
*/
@Override
public void onScaleEnd(ScaleGestureDetector detector) {
DebugLog.e("-----缩放手势结束-----");
}
});
}

@Override
public boolean onTouchEvent(MotionEvent event) {
mPointCount = event.getPointerCount();
return mScaleGestureDetector.onTouchEvent(event);
}

}

Hawky wechat
欢迎订阅我的微信公众号
坚持原创技术分享,您的支持将鼓励我继续创作!

分享