原文链接:http://developer.android.com/training/gestures/detector.html
检测常见的手势
当用户将一个或多个手指放置于屏幕上时,就会触发一个“触摸手势”,你的应用程序将触摸动作解释为一个特定的手势。手势检测分为两个阶段:
1.收集触摸事件的数据。
2.识别收集的数据,看它是否满足你的应用程序所支持手势的标准。
支持库中的类
这节中所用的例子使用了GestureDetectorCompat和MotionEventCompat类。这些类都在Support Library中。
收集数据
当用户将一个或多个手指放置于屏幕上时,就会触发接受到触摸事件的View的onTouchEvent()回调函数。对于每一个串触摸事件序列,最终被确定为一个手势,onTouchEvent()被触发多次。
手势以用户第一次触摸屏幕开始,系统将不断跟踪用户手指所在位置,最终通过用户手指离开屏幕作为结束。在整个交互中,MotionEvent被传入onTouchEvent()方法,提供了每一次交互的详细信息。你的应用使用由MotionEvent提供的数据来确定一个应用关注的手势是否发生。
捕获Activity或View的触摸事件
为了在Activity或View中捕获触摸事件,覆盖onTouchEvent()回调方法。
然后你可以自己处理这些事件来确定是否有手势动作发生。但是,如果你的应用使用一些常见的手势,例如双击,长按,滑动,等等,你可以使用GestureDetector类。GestureDetector能够使你更方便的检测常见手势,不用自己处理触摸事件。
捕获view的触摸事件
需要注意的是,如果对于ACTION_DOWN事件返回false,则这次事件序列中的ACTION_MOVE ACTION_UP事件将不会被处理。这是因为ACTION_DOWN是所有触摸事件的起点。
检测手势
检测所有支持的手势
当你初始化一个GestureDetectorCompat对象时,它需要的参数之一是一个类,实现了GestureDetector.OnGestureListener接口。当一个特定的触摸事件发生时,GestureDetector.OnGestureListener就会通知用户。为了使GestureDetector对象接收事件,你需要覆盖View或Activity的onTouchEvent函数,并将所有的events传递到detector实例。
检测所有手势的一个子集
如果你只想处理一部分手势,你可以继承GestureDetector.SimpleOnGestureListener。
GestureDetector.SimpleOnGestureListener提供了一个触摸事件的所有实现,所有函数的返回值都为false。因此你可以只覆盖那些你关心的方法。
不论是否使用GestureDetector.OnGestureListener,最好的做法就是实现onDown()函数并返回true。这是因为所有的手势都以onDown()消息开始。如果在onDown中返回false,则系统认为你想忽略剩余的手势动作,GestureDetector.OnGestureListener 将不会被调用。这将会给你的应用程序带来不可预期的问题。只有你想要忽略整个手势动作时,在onDown中返回false。
检测常见的手势
当用户将一个或多个手指放置于屏幕上时,就会触发一个“触摸手势”,你的应用程序将触摸动作解释为一个特定的手势。手势检测分为两个阶段:
1.收集触摸事件的数据。
2.识别收集的数据,看它是否满足你的应用程序所支持手势的标准。
支持库中的类
这节中所用的例子使用了GestureDetectorCompat和MotionEventCompat类。这些类都在Support Library中。
收集数据
当用户将一个或多个手指放置于屏幕上时,就会触发接受到触摸事件的View的onTouchEvent()回调函数。对于每一个串触摸事件序列,最终被确定为一个手势,onTouchEvent()被触发多次。
手势以用户第一次触摸屏幕开始,系统将不断跟踪用户手指所在位置,最终通过用户手指离开屏幕作为结束。在整个交互中,MotionEvent被传入onTouchEvent()方法,提供了每一次交互的详细信息。你的应用使用由MotionEvent提供的数据来确定一个应用关注的手势是否发生。
捕获Activity或View的触摸事件
为了在Activity或View中捕获触摸事件,覆盖onTouchEvent()回调方法。
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
|
public
class
MainActivity
extends
Activity {
...
// This example shows an Activity, but you would use the same approach if
// you were subclassing a View.
@Override
public
boolean
onTouchEvent(MotionEvent event){
int
action = MotionEventCompat.getActionMasked(event);
switch
(action) {
case
(MotionEvent.ACTION_DOWN) :
Log.d(DEBUG_TAG,
"Action was DOWN"
);
return
true
;
case
(MotionEvent.ACTION_MOVE) :
Log.d(DEBUG_TAG,
"Action was MOVE"
);
return
true
;
case
(MotionEvent.ACTION_UP) :
Log.d(DEBUG_TAG,
"Action was UP"
);
return
true
;
case
(MotionEvent.ACTION_CANCEL) :
Log.d(DEBUG_TAG,
"Action was CANCEL"
);
return
true
;
case
(MotionEvent.ACTION_OUTSIDE) :
Log.d(DEBUG_TAG,
"Movement occurred outside bounds "
+
"of current screen element"
);
return
true
;
default
:
return
super
.onTouchEvent(event);
}
}
|
然后你可以自己处理这些事件来确定是否有手势动作发生。但是,如果你的应用使用一些常见的手势,例如双击,长按,滑动,等等,你可以使用GestureDetector类。GestureDetector能够使你更方便的检测常见手势,不用自己处理触摸事件。
捕获view的触摸事件
|
01
02
03
04
05
06
07
|
View myView = findViewById(R.id.my_view);
myView.setOnTouchListener(
new
OnTouchListener() {
public
boolean
onTouch(View v, MotionEvent event) {
// ... Respond to touch events
return
true
;
}
});
|
需要注意的是,如果对于ACTION_DOWN事件返回false,则这次事件序列中的ACTION_MOVE ACTION_UP事件将不会被处理。这是因为ACTION_DOWN是所有触摸事件的起点。
检测手势
检测所有支持的手势
当你初始化一个GestureDetectorCompat对象时,它需要的参数之一是一个类,实现了GestureDetector.OnGestureListener接口。当一个特定的触摸事件发生时,GestureDetector.OnGestureListener就会通知用户。为了使GestureDetector对象接收事件,你需要覆盖View或Activity的onTouchEvent函数,并将所有的events传递到detector实例。
|
01
02
03
04
05
06
07
08
09
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
71
72
73
74
75
76
77
78
79
80
81
82
|
public
class
MainActivity
extends
Activity
implements
GestureDetector.OnGestureListener,
GestureDetector.OnDoubleTapListener{
private
static
final
String DEBUG_TAG =
"Gestures"
;
private
GestureDetectorCompat mDetector;
// Called when the activity is first created.
@Override
public
void
onCreate(Bundle savedInstanceState) {
super
.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Instantiate the gesture detector with the
// application context and an implementation of
// GestureDetector.OnGestureListener
mDetector =
new
GestureDetectorCompat(
this
,
this
);
// Set the gesture detector as the double tap
// listener.
mDetector.setOnDoubleTapListener(
this
);
}
@Override
public
boolean
onTouchEvent(MotionEvent event){
this
.mDetector.onTouchEvent(event);
// Be sure to call the superclass implementation
return
super
.onTouchEvent(event);
}
@Override
public
boolean
onDown(MotionEvent event) {
Log.d(DEBUG_TAG,
"onDown: "
+ event.toString());
return
true
;
}
@Override
public
boolean
onFling(MotionEvent event1, MotionEvent event2,
float
velocityX,
float
velocityY) {
Log.d(DEBUG_TAG,
"onFling: "
+ event1.toString()+event2.toString());
return
true
;
}
@Override
public
void
onLongPress(MotionEvent event) {
Log.d(DEBUG_TAG,
"onLongPress: "
+ event.toString());
}
@Override
public
boolean
onScroll(MotionEvent e1, MotionEvent e2,
float
distanceX,
float
distanceY) {
Log.d(DEBUG_TAG,
"onScroll: "
+ e1.toString()+e2.toString());
return
true
;
}
@Override
public
void
onShowPress(MotionEvent event) {
Log.d(DEBUG_TAG,
"onShowPress: "
+ event.toString());
}
@Override
public
boolean
onSingleTapUp(MotionEvent event) {
Log.d(DEBUG_TAG,
"onSingleTapUp: "
+ event.toString());
return
true
;
}
@Override
public
boolean
onDoubleTap(MotionEvent event) {
Log.d(DEBUG_TAG,
"onDoubleTap: "
+ event.toString());
return
true
;
}
@Override
public
boolean
onDoubleTapEvent(MotionEvent event) {
Log.d(DEBUG_TAG,
"onDoubleTapEvent: "
+ event.toString());
return
true
;
}
@Override
public
boolean
onSingleTapConfirmed(MotionEvent event) {
Log.d(DEBUG_TAG,
"onSingleTapConfirmed: "
+ event.toString());
return
true
;
}
}
|
检测所有手势的一个子集
如果你只想处理一部分手势,你可以继承GestureDetector.SimpleOnGestureListener。
GestureDetector.SimpleOnGestureListener提供了一个触摸事件的所有实现,所有函数的返回值都为false。因此你可以只覆盖那些你关心的方法。
不论是否使用GestureDetector.OnGestureListener,最好的做法就是实现onDown()函数并返回true。这是因为所有的手势都以onDown()消息开始。如果在onDown中返回false,则系统认为你想忽略剩余的手势动作,GestureDetector.OnGestureListener 将不会被调用。这将会给你的应用程序带来不可预期的问题。只有你想要忽略整个手势动作时,在onDown中返回false。
|
01
02
03
04
05
06
07
08
09
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
|
public
class
MainActivity
extends
Activity {
private
GestureDetectorCompat mDetector;
@Override
public
void
onCreate(Bundle savedInstanceState) {
super
.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mDetector =
new
GestureDetectorCompat(
this
,
new
MyGestureListener());
}
@Override
public
boolean
onTouchEvent(MotionEvent event){
this
.mDetector.onTouchEvent(event);
return
super
.onTouchEvent(event);
}
class
MyGestureListener
extends
GestureDetector.SimpleOnGestureListener {
private
static
final
String DEBUG_TAG =
"Gestures"
;
@Override
public
boolean
onDown(MotionEvent event) {
Log.d(DEBUG_TAG,
"onDown: "
+ event.toString());
return
true
;
}
@Override
public
boolean
onFling(MotionEvent event1, MotionEvent event2,
float
velocityX,
float
velocityY) {
Log.d(DEBUG_TAG,
"onFling: "
+ event1.toString()+event2.toString());
return
true
;
}
}
}
|
本文介绍如何在Android应用中检测触摸手势,包括使用GestureDetectorCompat类处理常见的手势如滑动、长按等。文章提供了示例代码,展示如何设置手势监听器及处理触摸事件。
673

被折叠的 条评论
为什么被折叠?



