Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android Developers:檢測常見的手勢

Android Developers:檢測常見的手勢

編輯:關於Android編程

”觸摸手勢“發生在用戶放置一個或者多個手指在觸摸屏上的時候,然後你的應用程序翻譯這個觸摸模型作為一個特別的手勢。手勢檢測有相應的兩個階段:

  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方法返回一個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方法的一個實現,所有返回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; 
           } 
       } 
    } 

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved