Android 手势识别

以前进行用户手指触摸事件动作的时候都是在 onTouchEvent 方法中对用户的的触摸进行监听和计算,以判断用户的意图和执行必要的逻辑。但是一些需求如果全部在这个方法中进行计算,就显得过于臃肿,同时导致该方法中逻辑杂乱,不易分辨。

Android 中额外提供了 GestureDetector 这个类,用于专门计算用户的手势,该类的监听接口中支持点击、长按、滑动、滚动、轻触等事件。

下面一起来看看如何使用手势识别器。

定义一个手势识别器

这个再简单不过了

1
private GestureDetector mDetector;

实例化手势识别器

在 Activity 的 onCreate 实例化的同时,需要为手势识别器添加监听接口,与其他监听接口的使用一样,可以使用匿名内部类和外部类等多种方式,这里我就是直接使用匿名内部类了。

这里我的需求是,监测用户的触摸滑动,识别出翻页的动作。也就是切换 Activity 的意图,大概跟 ViewPager 的功能类似,但是不能实现 ViewPager 的页面随手指一起移动的 feature。

根据我的需求,我只需要重写接口中的 onFling 也就是滑动事件。具体的代码意义直接在代码中标明了。

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
mDetector=new GestureDetector(this, new GestureDetector.OnGestureListener() {
@Override
public boolean onDown(MotionEvent e) {//按下,每次按下都会识别
return false;
}

@Override
public void onShowPress(MotionEvent e) {//按下但是尚未抬起或移动

}

@Override
public boolean onSingleTapUp(MotionEvent e) {//按下并立刻抬起
return false;
}

@Override
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
//滚动
return false;
}

@Override
public void onLongPress(MotionEvent e) {//长按

}

/**
*
* @param e1 开始的触摸动作
* @param e2 结束的触摸动作
* @param velocityX X轴滑动速度 px/s
* @param velocityY Y轴滑动速度 px/s
* @return 是否消费该事件
*/
@Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
if (Math.abs(e1.getRawY() - e2.getRawY()) > 100) {
//若在纵轴的划动超过100px,换页意图不明显,不再进行事件处理
return true;
}
if (e1.getRawX() - e2.getRawX() > 200) {
//若向左滑动超过200px
Next();
return true;
}
if (e2.getRawX() - e1.getRawX() > 200) {
//若向右滑动超过200px
Pre();
return true;
}
return false;
}
});

将触摸事件传递至手势识别器

此时手势识别器虽然定义好了,但是很明显,我们还尚未使用它。重写 onTouchEvent ,将用户的触摸事件传递给手势识别器,然后手势识别器就可以对传入的动作进行分析了。

1
2
3
4
5
@Override
public boolean onTouchEvent(MotionEvent event) {
mDetector.onTouchEvent(event);
return super.onTouchEvent(event);
}

手势识别配合窗口切换动画一起服用,效果更佳哟。