Android Developers:检测常见的手势

”触摸手势“发生在用户放置一个或者多个手指在触摸屏上的时候,然后你的应用程序翻译这个触摸模型作为一个特别的手势。手势检测有相应的两个阶段: 

  1. 采集关于触摸事件的数据 

  2. 翻译这个数据去查看它是否符合你的应用程序支持的任何手势的标准 

支持库类 

在这个课程中的例子使用了GestureDetectorCompat和MotionEventCompat类。这些类都在Support Library中。你应该在可能提供兼容性,运行Android1.6和更高的设备中使用支持库类。注意MotionEventCompat不是MotionEvent类的一个替代。当然,它提供了静态实体方法,你传递给你的MotionEvent对象,为了获取和事件相关的期望的动作。 

 

采集数据 

————————————————————————————————————————————— 

当用户放置一个或者多个手指在屏幕上的时候,触发在获取触摸事件的视图中的onTouchEvent()方法。对于每个序列的触摸事件(position.pressure,size,addition of another finder,ect.)最终确定为一个手势,onTouchEvent()方法被触发几次 

 

手势从用户第一次触摸屏幕的时候开始,随着系统跟踪用户手指的位置而继续,最后以捕获用户手指离开屏幕的最后事件结束。整个交互中,MotionEvent被分传递给onTouchEvent()方法,提供了每个交互的详细说明。你的应用程序能使用通过MotionEvent提供的数据,来确定一个手势是否发生 

 

为Activiyt或者View中捕获触摸事件 

为了截取在Activity或者View中的触摸事件,覆盖onTouchEvent()回调方法 

 

下面的代码块使用了getActionMasked()方法,从event参数中提取用户执行的动作。它给你提供了用来决定一个手势是否发生的原始数据 

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不处理个人的触摸事件,使检测通常的手势对于你变得简单。这个在下面Detect Gestures中被讨论  

 

为单独的View捕获触摸事件 

作为onTouchEvent()方法供替代的选择,你能使用setOnTouchListener()方法给任何View附加一个View.onTouchListener对象。这使的监听触摸事件,但没有子类化一个已存在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是所有触摸事件的起点。  

 

如果你创建一个自定义的View,你能覆盖onTouchEvent()方法,如上面所描述的 

 

检测手势 

——————————————————————————————————————————————————————————————————————

Android提供了GestureDetector类来检测普通的手势。它支持的一些手势包括onDown(),onLongPress(),onFling(),等等。你能结合上面描述的onTouchEvent()方法使用GestureDetector类 

 

检测所有支持的手势 

当你实例化一个GestureDectectorCompat对象的时候,它使用的一个参数是一个实现了GestureDectector.onGestureListener接口的类。当一个特定的触摸事件发生的时候,GestureDetector.onGestureListener通知用户。为了使你的GestureDetector对象获取这个事件变成可能,你覆盖这个View或者Activity的onTouchEvent()方法,并传递所可被观察到的事件给这个检测者实例 
 

在下面的代码块中,从各个on<TouchEvenet>方法返回一个true值,说明了你已经处理了这个事件。一个false返回值传递事件到这个View栈,直到这个触摸已经被成功的处理。 
 

运行下面的代码块,感受一下当你和触摸屏交互的时候,操作是如何被触发的,和每个触摸事件的MetionEventneo内容。你将会认识到简单的交互生成了如此多的数据。 

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替代实现GestureDectector.onGestureListener接口。 

 

GestureDetector.SimpleOnGestureListener提供了所有on<TouchEvent>方法的一个实现,所有返回false。因此你能仅仅覆盖你关心的方法。例如,下面的代码块创建了一个类,它继承了GestureDectedtor.SimpleonGestureListener,并且覆盖了onFling()和onDown()方法 

 

不论你是否使用GestureDectector.onGestureListener,实现一个onDown()方法的最好实践是返回ture。这个是因为所有的手势都是以onDown()消息开始的。如果你从onDown()方法返回false,如GestureDectector.SimpleOnGestureListener默认行为,这个系统假设你不会理睬其余的手势,并且其它GestureDectector.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; 
       } 
   } 
} 

新技术,新未来!欢迎大家关注 “1024工场”微信服务号 ,时刻关注我们的最新的技术讯息! (甭客气!尽情的扫描或者长按!)

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值