android:onTouch()和onTouchEvent()的区别?看完这篇文章就知道了

来源:互联网 发布:电脑连接wifi后网络慢 编辑:程序博客网 时间:2024/05/16 00:48

(转载)http://www.oschina.net/question/54100_28968?fromerr=0EyHuwoH

Android Touch Screen 与传统Click Touch Screen不同,会有一些手势(Gesture),例如Fling,Scroll等等。这些Gesture会使用户体验大大提升。

Android中的Gesture识别(detector)是通过GestureDetector.OnGestureListener接口实现的。

首先,Android事件处理机制是基于Listener实现的,比如触摸屏相关的事件,就是通过onTouchListener实现;

其次,所有View的子类都可以通过setOnTouchListener()、setOnKeyListener()等方法来添加对某一类事件的Listener;

第三,Listener一般会以Interface的方式来提供,其中包含一个或多个abstract方法,我们需要实现这些方法来完成onTouch()、onKey()等操作。这样,程序便可以在特定的事件被dispatch到该view的时候,通过callback函数给予适当的响 应。

1. Touch Screen Click举例

?
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
publicclass MyGesture extendsActivity implementsOnTouchListener
 
{
 
publicvoid onCreate(Bundle savedInstanceState)
 
{
 
super.onCreate(savedInstanceState);
 
setContentView(R.layout.main);
 
TextView tv = (TextView) findViewById(R.id.tv);
 
tv.setOnTouchListener(this);
 
}
 
publicboolean onTouch(View v, MotionEvent event)
 
{
 
Toast.makeText(this,"Touch Touch", Toast.LENGTH_SHORT).show();
 
returnfalse;
 
}
 
}

我们可以通过MotionEvent的getAction()方法来获取Touch事件的类型,包括 ACTION_DOWN(按下触摸屏), ACTION_MOVE(按下触摸屏后移动受力点), ACTION_UP(松开触摸屏)和ACTION_CANCEL(不会由用户直接触发)。借助对于用户不同操作的判断,结合getRawX()、getRawY()、getX()和getY()等方法来获取坐标后,我们可以实现诸如拖动某一个按钮,拖动滚动条等功能。

2. 当我们捕捉到Touch操作的时候,如何识别出用户的Gesture?这里我们需要GestureDetector.OnGestureListener接口的帮助,代码如下:

?
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
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
publicclass MyGesture extendsActivity implementsOnTouchListener, OnGestureListener
 
{
 
privateGestureDetector mGestureDetector;
 
publicMyGesture()
 
{
 
mGestureDetector = newGestureDetector(this);
 
}
 
publicvoid onCreate(Bundle savedInstanceState)
 
{
 
super.onCreate(savedInstanceState);
 
setContentView(R.layout.main);
 
TextView tv = (TextView) findViewById(R.id.tv);
 
tv.setOnTouchListener(this);
 
tv.setFocusable(true);
 
tv.setClickable(true);
 
tv.setLongClickable(true);
 
mGestureDetector.setIsLongpressEnabled(true);
 
}
 
/* * 在onTouch()方法中,我们调用GestureDetector的onTouchEvent()方法,将捕捉到的MotionEvent交给GestureDetector * 来分析是否有合适的callback函数来处理用户的手势 */
 
publicboolean onTouch(View v, MotionEvent event)
 
{
 
returnmGestureDetector.onTouchEvent(event);
 
}
 
// 用户轻触触摸屏,由1个MotionEvent ACTION_DOWN触发
 
publicboolean onDown(MotionEvent arg0)
 
{
 
Log.i("MyGesture","onDown");
 
Toast.makeText(this,"onDown", Toast.LENGTH_SHORT).show();
 
returntrue;
 
}
 
/* * 用户轻触触摸屏,尚未松开或拖动,由一个1个MotionEvent ACTION_DOWN触发 * 注意和onDown()的区别,强调的是没有松开或者拖动的状态 */
 
publicvoid onShowPress(MotionEvent e)
 
{
 
Log.i("MyGesture","onShowPress");
 
Toast.makeText(this,"onShowPress", Toast.LENGTH_SHORT).show();
 
}
 
// 用户(轻触触摸屏后)松开,由一个1个MotionEvent ACTION_UP触发
 
publicboolean onSingleTapUp(MotionEvent e)
 
{
 
Log.i("MyGesture","onSingleTapUp");
 
Toast.makeText(this,"onSingleTapUp", Toast.LENGTH_SHORT).show();
 
returntrue;
 
}
 
// 用户按下触摸屏、快速移动后松开,由1个MotionEvent ACTION_DOWN, 多个ACTION_MOVE, 1个ACTION_UP触发
 
publicboolean onFling(MotionEvent e1, MotionEvent e2, floatvelocityX, floatvelocityY)
 
{
 
Log.i("MyGesture","onFling");
 
Toast.makeText(this,"onFling", Toast.LENGTH_LONG).show();
 
returntrue;
 
}
 
// 用户按下触摸屏,并拖动,由1个MotionEvent ACTION_DOWN, 多个ACTION_MOVE触发
 
publicboolean onScroll(MotionEvent e1, MotionEvent e2, floatdistanceX, floatdistanceY)
 
{
 
Log.i("MyGesture","onScroll");
 
Toast.makeText(this,"onScroll", Toast.LENGTH_LONG).show();
 
returntrue;
 
}
 
// 用户长按触摸屏,由多个MotionEvent ACTION_DOWN触发
 
publicvoid onLongPress(MotionEvent e)
 
{
 
Log.i("MyGesture","onLongPress");
 
Toast.makeText(this,"onLongPress", Toast.LENGTH_LONG).show();
 
}
 
}

3. Fling事件的处理代码:除了第一个触发Fling的ACTION_DOWN和最后一个ACTION_MOVE中包含的坐标等信息外,我们还可以根据用 户在X轴或者Y轴上的移动速度作为条件。比如下面的代码中我们就在用户移动超过100个像素,且X轴上每秒的移动速度大于200像素时才进行处理。

?
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
publicboolean onFling(MotionEvent e1, MotionEvent e2, floatvelocityX, floatvelocityY)
 
{
 
// 参数解释:
 
// e1:第1个ACTION_DOWN MotionEvent
 
// e2:最后一个ACTION_MOVE MotionEvent
 
// velocityX:X轴上的移动速度,像素/秒
 
// velocityY:Y轴上的移动速度,像素/秒
 
// 触发条件 :
 
// X轴的坐标位移大于FLING_MIN_DISTANCE,且移动速度大于FLING_MIN_VELOCITY个像素/秒
 
finalint FLING_MIN_DISTANCE = 100, FLING_MIN_VELOCITY = 200;
 
if(e1.getX() - e2.getX() > FLING_MIN_DISTANCE && Math.abs(velocityX) > FLING_MIN_VELOCITY)
 
{
 
// Fling left
 
Log.i("MyGesture","Fling left");
 
Toast.makeText(this,"Fling Left", Toast.LENGTH_SHORT).show();
 
}
 
elseif (e2.getX() - e1.getX() > FLING_MIN_DISTANCE && Math.abs(velocityX) > FLING_MIN_VELOCITY)
 
{
 
// Fling right
 
Log.i("MyGesture","Fling right");
 
Toast.makeText(this,"Fling Right", Toast.LENGTH_SHORT).show();
 
}
 
returnfalse;
 
}

这个例子中,tv.setLongClickable(true)是必须的,因为只有这样,view才能够处理不同于Tap(轻触)的hold(即ACTION_MOVE,或者多个ACTION_DOWN),我们同样可以通过layout定义中的android:longClickable来做到这一点。
0 0
原创粉丝点击