检测常见的手势 当用户将一个或多个手指放置于屏幕上时,就会触发一个“触摸手势”,你的应用程序将触摸动作解释为一个特定的手势。手势检测分为两个阶段: 1.收集触摸事件的数据。 2.识别收集的数据,看它是否满足你的应用程序所支持手势的标准。 支持库中的类 这节中所用的例子使用了GestureDetectorCompat和MotionEventCompat类。这些类都在Support Library中。 收集数据 当用户将一个或多个手指放置于屏幕上时,就会触发接受到触摸事件的View的onTouchEvent()回调函数。对于每一个串触摸事件序列,最终被确定为一个手势,onTouchEvent()被触发多次。 手势以用户第一次触摸屏幕开始,系统将不断跟踪用户手指所在位置,最终通过用户手指离开屏幕作为结束。在整个交互中,MotionEvent被传入onTouchEvent()方法,提供了每一次交互的详细信息。你的应用使用由MotionEvent提供的数据来确定一个应用关注的手势是否发生。 捕获Activity或View的触摸事件 为了在Activity或View中捕获触摸事件,覆盖onTouchEvent()回调方法。

代码片段,双击复制

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的触摸事件

代码片段,双击复制

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实例。

代码片段,双击复制

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。

代码片段,双击复制

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         ;        
                  }        
                  }        
         }