Android 触摸及手势操作GestureDetector

 现在的智能手机不敢说百分百的都是触摸屏,也应该是百分之九九以上为触摸屏了,触摸屏为我们操作无键盘、无鼠标的手机系统带来了很多的便利。当用户触摸屏幕时会产生很多的触摸事件,down、up、move等等。View类有个View.OnTouchListener内部接口,通过重写他的onTouch(View v, MotionEvent event)方法,我们可以处理一些touch事件,如下:

 

  1. public class MainActivity extends Activity {  
  2. ...  
  3. // This example shows an Activity, but you would use the same approach if  
  4. // you were subclassing a View.  
  5. @Override  
  6. public boolean onTouchEvent(MotionEvent event){   
  7.           
  8.     int action = MotionEventCompat.getActionMasked(event);  
  9.           
  10.     switch(action) {  
  11.         case (MotionEvent.ACTION_DOWN) :  
  12.             Log.d(DEBUG_TAG,"Action was DOWN");  
  13.             return true;  
  14.         case (MotionEvent.ACTION_MOVE) :  
  15.             Log.d(DEBUG_TAG,"Action was MOVE");  
  16.             return true;  
  17.         case (MotionEvent.ACTION_UP) :  
  18.             Log.d(DEBUG_TAG,"Action was UP");  
  19.             return true;  
  20.         case (MotionEvent.ACTION_CANCEL) :  
  21.             Log.d(DEBUG_TAG,"Action was CANCEL");  
  22.             return true;  
  23.         case (MotionEvent.ACTION_OUTSIDE) :  
  24.             Log.d(DEBUG_TAG,"Movement occurred outside bounds " +  
  25.                     "of current screen element");  
  26.             return true;        
  27.         default :   
  28.             return super.onTouchEvent(event);  
  29.     }        
  30. }  



 

    OnTouch提供的事件还是相对较简单,如果需要处理一些复杂的手势,用这个接口就会很麻烦,因为我们要根据用户触摸的轨迹去判断是什么手势。Android sdk给我们提供了GestureDetector(Gesture:手势Detector:识别)类,通过这个类我们可以识别很多的手势。

 

public class GestureDetector extends Object    

java.lang.Object

android.view.GestureDetector

    GestureDetector属于android.view包,android还提供了android.gesture包支持更多的手势操作,以后我们会介绍到。官方的介绍中使用了GestureDetectorCompat处理手势识别,为什么使用GestureDetectorCompat替换了GestureDetector呢,官方的是这样解释的:


 

  GestureDetectorCompat实例化有下面两种方法


    

    GestureDetector类对外提供了两个接口:OnGestureListener,OnDoubleTapListener,还有一个内部类SimpleOnGestureListener;SimpleOnGestureListener类是GestureDetector提供给我们的一个更方便的响应不同手势的类,它实现了上述两个接口,该类是static class,也就是说它实际上是一个外部类,我们可以在外部继承这个类,重写里面的手势处理方法。因此实现手势识别有两种方法,一种实现OnGestureListener接口,另一种是使用SimpleOnGestureListener类。

 

    使用OnGestureListener接口,这样需要重载OnGestureListener接口所有的方法,适合监听所有的手势,正如官方文档提到的“Detecing All Supported Gestures”。

 

  1. public class MainActivity extends Activity implements   
  2.         GestureDetector.OnGestureListener,  
  3.         GestureDetector.OnDoubleTapListener{  
  4.       
  5.     private static final String DEBUG_TAG = "Gestures";  
  6.     private GestureDetectorCompat mDetector;   
  7.   
  8.     // Called when the activity is first created.   
  9.     @Override  
  10.     public void onCreate(Bundle savedInstanceState) {  
  11.         super.onCreate(savedInstanceState);  
  12.         setContentView(R.layout.activity_main);  
  13.         // Instantiate the gesture detector with the  
  14.         // application context and an implementation of  
  15.         // GestureDetector.OnGestureListener  
  16.         mDetector = new GestureDetectorCompat(this,this);  
  17.         // Set the gesture detector as the double tap  
  18.         // listener.  
  19.         mDetector.setOnDoubleTapListener(this);  
  20.     }  
  21.   
  22.     @Override   
  23.     public boolean onTouchEvent(MotionEvent event){   
  24.         this.mDetector.onTouchEvent(event);  
  25.         // Be sure to call the superclass implementation  
  26.         return super.onTouchEvent(event);  
  27.     }  
  28.   
  29.     @Override  
  30.     public boolean onDown(MotionEvent event) {   
  31.         Log.d(DEBUG_TAG,"onDown: " + event.toString());   
  32.         return true;  
  33.     }  
  34.   
  35.     @Override  
  36.     public boolean onFling(MotionEvent event1, MotionEvent event2,   
  37.             float velocityX, float velocityY) {  
  38.         Log.d(DEBUG_TAG, "onFling: " + event1.toString()+event2.toString());  
  39.         return true;  
  40.     }  
  41.   
  42.     @Override  
  43.     public void onLongPress(MotionEvent event) {  
  44.         Log.d(DEBUG_TAG, "onLongPress: " + event.toString());   
  45.     }  
  46.   
  47.     @Override  
  48.     public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX,  
  49.             float distanceY) {  
  50.         Log.d(DEBUG_TAG, "onScroll: " + e1.toString()+e2.toString());  
  51.         return true;  
  52.     }  
  53.   
  54.     @Override  
  55.     public void onShowPress(MotionEvent event) {  
  56.         Log.d(DEBUG_TAG, "onShowPress: " + event.toString());  
  57.     }  
  58.   
  59.     @Override  
  60.     public boolean onSingleTapUp(MotionEvent event) {  
  61.         Log.d(DEBUG_TAG, "onSingleTapUp: " + event.toString());  
  62.         return true;  
  63.     }  
  64.   
  65.     @Override  
  66.     public boolean onDoubleTap(MotionEvent event) {  
  67.         Log.d(DEBUG_TAG, "onDoubleTap: " + event.toString());  
  68.         return true;  
  69.     }  
  70.   
  71.     @Override  
  72.     public boolean onDoubleTapEvent(MotionEvent event) {  
  73.         Log.d(DEBUG_TAG, "onDoubleTapEvent: " + event.toString());  
  74.         return true;  
  75.     }  
  76.   
  77.     @Override  
  78.     public boolean onSingleTapConfirmed(MotionEvent event) {  
  79.         Log.d(DEBUG_TAG, "onSingleTapConfirmed: " + event.toString());  
  80.         return true;  
  81.     }  
  82. }  


这样会造成有些手势我们用不到,但是还要重载。SimpleOnGestureListener类的出现为我们解决了这个问题,如果你想“Detecting a Subset of Supported Gestures”,SimpleOnGestureListener是最好的选择。

 

 

  1. public class MainActivity extends Activity {   
  2.       
  3.     private GestureDetectorCompat mDetector;   
  4.   
  5.     @Override  
  6.     public void onCreate(Bundle savedInstanceState) {  
  7.         super.onCreate(savedInstanceState);  
  8.         setContentView(R.layout.activity_main);  
  9.         mDetector = new GestureDetectorCompat(thisnew MyGestureListener());  
  10.     }  
  11.   
  12.     @Override   
  13.     public boolean onTouchEvent(MotionEvent event){   
  14.         this.mDetector.onTouchEvent(event);  
  15.         return super.onTouchEvent(event);  
  16.     }  
  17.       
  18.     class MyGestureListener extends GestureDetector.SimpleOnGestureListener {  
  19.         private static final String DEBUG_TAG = "Gestures";   
  20.           
  21.         @Override  
  22.         public boolean onDown(MotionEvent event) {   
  23.             Log.d(DEBUG_TAG,"onDown: " + event.toString());   
  24.             return true;  
  25.         }  
  26.   
  27.         @Override  
  28.         public boolean onFling(MotionEvent event1, MotionEvent event2,   
  29.                 float velocityX, float velocityY) {  
  30.             Log.d(DEBUG_TAG, "onFling: " + event1.toString()+event2.toString());  
  31.             return true;  
  32.         }  
  33.     }  
  34. }  



 

    最后了我们也解释两个问题:

    1、onTouchEvent中为什么使用了MotionEventCompat,而不直接使用MotionEvent。因为MotionEventCompat使更多的Action适配到API 4。

    2、Android的view怎么使用手势,方法如下:

 

  1. View myView = findViewById(R.id.my_view);   
  2.     myView.setOnTouchListener(new OnTouchListener() {  
  3.         public boolean onTouch(View v, MotionEvent event) {  
  4.             // ... Respond to touch events         
  5.             this.mDetector.onTouchEvent(event);  
  6.             return super.onTouchEvent(event);  
  7.         }  
  8.     });  

 

 

 

/**
* @author 张兴业
*  iOS入门群:83702688
*  android开发进阶群:241395671
*  我的新浪微博:@张兴业TBOW
*/
 
 

 

参考:

http://developer.android.com/reference/android/view/GestureDetector.html

http://developer.android.com/training/gestures/detector.html

posted @ 2013-11-21 19:05  张兴业  阅读(1022)  评论(0编辑  收藏  举报