[Android分享] 使用触摸手势(一)

来源:互联网 发布:java连接数据库的代码 编辑:程序博客网 时间:2024/05/22 17:21
原文链接: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()回调方法。
?
代码片段,双击复制
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
publicclass MainActivity extendsActivity {
...
// This example shows an Activity, but you would use the same approach if
// you were subclassing a View.
@Override
publicboolean onTouchEvent(MotionEvent event){
         
   intaction = MotionEventCompat.getActionMasked(event);
         
   switch(action) {
        case(MotionEvent.ACTION_DOWN) :
            Log.d(DEBUG_TAG,"Action was DOWN");
            returntrue;
        case(MotionEvent.ACTION_MOVE) :
            Log.d(DEBUG_TAG,"Action was MOVE");
            returntrue;
        case(MotionEvent.ACTION_UP) :
            Log.d(DEBUG_TAG,"Action was UP");
            returntrue;
        case(MotionEvent.ACTION_CANCEL) :
            Log.d(DEBUG_TAG,"Action was CANCEL");
            returntrue;
        case(MotionEvent.ACTION_OUTSIDE) :
            Log.d(DEBUG_TAG,"Movement occurred outside bounds " +
                    "of current screen element");
            returntrue;      
        default:
            returnsuper.onTouchEvent(event);
   }      
}

然后你可以自己处理这些事件来确定是否有手势动作发生。但是,如果你的应用使用一些常见的手势,例如双击,长按,滑动,等等,你可以使用GestureDetector类。GestureDetector能够使你更方便的检测常见手势,不用自己处理触摸事件。

捕获view的触摸事件
?
代码片段,双击复制
01
02
03
04
05
06
07
View myView = findViewById(R.id.my_view);
myView.setOnTouchListener(newOnTouchListener() {
   publicboolean onTouch(View v, MotionEvent event) {
        // ... Respond to touch events      
        returntrue;
   }
});

需要注意的是,如果对于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
publicclass MainActivity extendsActivity implements
        GestureDetector.OnGestureListener,
        GestureDetector.OnDoubleTapListener{
    
   privatestatic final String DEBUG_TAG = "Gestures";
   privateGestureDetectorCompat mDetector;
 
   // Called when the activity is first created.
   @Override
   publicvoid 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 = newGestureDetectorCompat(this,this);
        // Set the gesture detector as the double tap
        // listener.
        mDetector.setOnDoubleTapListener(this);
   }
 
   @Override
   publicboolean onTouchEvent(MotionEvent event){
        this.mDetector.onTouchEvent(event);
        // Be sure to call the superclass implementation
        returnsuper.onTouchEvent(event);
   }
 
   @Override
   publicboolean onDown(MotionEvent event) {
        Log.d(DEBUG_TAG,"onDown: " + event.toString());
        returntrue;
   }
 
   @Override
   publicboolean onFling(MotionEvent event1, MotionEvent event2,
            floatvelocityX, floatvelocityY) {
        Log.d(DEBUG_TAG,"onFling: " + event1.toString()+event2.toString());
        returntrue;
   }
 
   @Override
   publicvoid onLongPress(MotionEvent event) {
        Log.d(DEBUG_TAG,"onLongPress: " + event.toString());
   }
 
   @Override
   publicboolean onScroll(MotionEvent e1, MotionEvent e2, floatdistanceX,
            floatdistanceY) {
        Log.d(DEBUG_TAG,"onScroll: " + e1.toString()+e2.toString());
        returntrue;
   }
 
   @Override
   publicvoid onShowPress(MotionEvent event) {
        Log.d(DEBUG_TAG,"onShowPress: " + event.toString());
   }
 
   @Override
   publicboolean onSingleTapUp(MotionEvent event) {
        Log.d(DEBUG_TAG,"onSingleTapUp: " + event.toString());
        returntrue;
   }
 
   @Override
   publicboolean onDoubleTap(MotionEvent event) {
        Log.d(DEBUG_TAG,"onDoubleTap: " + event.toString());
        returntrue;
   }
 
   @Override
   publicboolean onDoubleTapEvent(MotionEvent event) {
        Log.d(DEBUG_TAG,"onDoubleTapEvent: " + event.toString());
        returntrue;
   }
 
   @Override
   publicboolean onSingleTapConfirmed(MotionEvent event) {
        Log.d(DEBUG_TAG,"onSingleTapConfirmed: " + event.toString());
        returntrue;
   }
}


检测所有手势的一个子集

如果你只想处理一部分手势,你可以继承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
publicclass MainActivity extendsActivity {
    
   privateGestureDetectorCompat mDetector;
 
   @Override
   publicvoid onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mDetector = newGestureDetectorCompat(this,newMyGestureListener());
   }
 
   @Override
   publicboolean onTouchEvent(MotionEvent event){
        this.mDetector.onTouchEvent(event);
        returnsuper.onTouchEvent(event);
   }
    
   classMyGestureListener extendsGestureDetector.SimpleOnGestureListener {
        privatestatic final String DEBUG_TAG = "Gestures";
         
        @Override
        publicboolean onDown(MotionEvent event) {
            Log.d(DEBUG_TAG,"onDown: " + event.toString());
            returntrue;
        }
 
        @Override
        publicboolean onFling(MotionEvent event1, MotionEvent event2,
                floatvelocityX, floatvelocityY) {
            Log.d(DEBUG_TAG,"onFling: " + event1.toString()+event2.toString());
            returntrue;
        }
   }
}