Android手勢監聽類GestureDetector

GestureDetector類及其用法

Android sdk 給我們提供了GestureDetector(Gesture:手勢,Detector:識別)類,通過這個類我們可以識別很多的手勢,主要是通過他的onTouchEvent(event)方法完成了不同手勢的識別。

GestureDetector這個類對外提供了兩個接口:OnGestureListener,OnDoubleTapListener,還有一個內部類SimpleOnGestureListener。


GestureDetector.OnDoubleTapListener接口:用來通知DoubleTap事件,類似於鼠標的雙擊事件,該接口有如下三個回調函數:
        1. onDoubleTap(MotionEvent e):在雙擊的第二下按下時觸發 。
        2. onDoubleTapEvent(MotionEvent e):通知DoubleTap手勢中的事件,包含down、up和move事件(這裏指的是在雙擊之間發生的事件,例如在同一個地方雙擊會產生DoubleTap手勢,而在DoubleTap手勢裏面還會發生down和up事件,這兩個事件由該函數通知);雙擊的第二下按下和擡起時都會觸發,可用e.getAction()區分。 

        3. onSingleTapConfirmed(MotionEvent e):用來判定該次點擊是SingleTap而不是DoubleTap,如果連續點擊兩次就是DoubleTap手勢;如果只點擊一次,系統等待一段時間後沒有收到第二次點擊則判定該次點擊爲SingleTap而不是DoubleTap,然後觸發SingleTapConfirmed事件。這個方法不同於onSingleTapUp,它是在GestureDetector確信用戶在第一次觸摸屏幕後,沒有緊跟着第二次觸摸屏幕,也就是不是“雙擊”的時候觸發。

 

GestureDetector.OnGestureListener接口:用來通知普通的手勢事件,該接口有如下六個回調函數:
     1.   onDown(MotionEvent e):按下事件;
     2.   onSingleTapUp(MotionEvent e):單擊時,在按下後既沒有滑動(onScroll),又沒有長按(onLongPress),然後擡起時觸發。
          點擊一下非常快的(不滑動)Touchup:onDown->onSingleTapUp->onSingleTapConfirmed 
          點擊一下稍微慢點的(不滑動)Touchup:onDown->onShowPress->onSingleTapUp->onSingleTapConfirmed

     3.   onShowPress(MotionEvent e):down事件發生而move或up還沒發生前,觸發該事件;Touch了但還沒有滑動時觸發。

      與onDown,onLongPress比較:onDown只要按下一定立刻觸發。而按下後過一會沒有滑動先觸發onShowPress再是onLongPress。如,按下後一直不滑動,觸發順序onDown-->onShowPress-->onLongPress。 

     4.   onLongPress(MotionEvent e):長按事件;Touch了不移動一直Touch down時觸發。 
     5.   onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY):滑動手勢事件;Touch了滑動一點距離後,在擡起時纔會觸發。      

     參數:e1,第1個ACTION_DOWN MotionEvent 並且只有一個;e2,最後一個ACTION_MOVE MotionEvent ;velocityX,X軸上的移動速度(像素/秒);velocityY,Y軸上的移動速度(像素/秒)。

     觸發條件:X軸的座標位移大於FLING_MIN_DISTANCE,且移動速度大於FLING_MIN_VELOCITY個像素/秒時。

     6.   onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY):在屏幕上拖動事件。在ACTION_MOVE動作發生時觸發,會多次觸發。onDown-->onScroll-->onScroll-->onFiling
 
SimpleOnGestureListener類是GestureDetector提供給我們的一個更方便的響應不同手勢的類,這個類實現了上述兩個接口(但是所有的方法體都是空的),該類是static class,也就是說它實際上是一個外部類。可以在外部繼承這個類,重寫裏面的手勢處理方法。
 

    方法步驟:


    第一種:

    1,通過GestureDetector的構造方法將SimpleOnGestureListener對象傳遞進去,這樣GestureDetector能處理不同的手勢了。

  1. <span style="font-family:SimSun;">    </span><span style="font-family:SimSun;">public GestureDetector(Context context, GestureDetector.OnGestureListener listener)</span>  

    2,在OnTouchListener的onTouch方法中

  1. private OnTouchListener gestureTouchListener = new OnTouchListener()   
  2. {  
  3.     public boolean onTouch(View v, MotionEvent event)   
  4.     {  
  5.          return gDetector.onTouchEvent(event);  
  6.     }  
  7. };  

     第二種:

  1. private GestureDetector mGestureDetector;  
  2. mGestureListener = new BookOnGestureListener();  
  3. mGestureDetector = new GestureDetector(mGestureListener);  
  4. class BookOnGestureListener implements OnGestureListener   
  5. {  
  6.     public boolean onTouchEvent(MotionEvent event)   
  7.     {  
  8.          mGestureListener.onTouchEvent(event);  
  9.     }  
  10. }  

第三種:
  1. <span style="font-family:SimSun;">private GestureDetector mGestureDetector;  
  2. @Override  
  3. public void onCreate(Bundle savedInstanceState)  
  4. {  
  5.     super.onCreate(savedInstanceState);  
  6.     mGestureDetector = new GestureDetector(thisnew LearnGestureListener());  
  7. }  
  8. @Override  
  9. public boolean onTouchEvent(MotionEvent event)   
  10. {  
  11.     if (mGestureDetector.onTouchEvent(event))  
  12.       return true;  
  13.     else  
  14.         return false;  
  15. }  
  16. private class LearnGestureListener extends GestureDetector.SimpleOnGestureListener  
  17. {  
  18.     @Override  
  19.     public boolean onSingleTapUp(MotionEvent ev)   
  20.     {  
  21.         Log.d("onSingleTapUp",ev.toString());  
  22.         return true;  
  23.     }  
  24.     @Override  
  25.     public void onShowPress(MotionEvent ev)   
  26.     {  
  27.         Log.d("onShowPress",ev.toString());  
  28.     }  
  29.     @Override  
  30.     public void onLongPress(MotionEvent ev)   
  31.     {  
  32.         Log.d("onLongPress",ev.toString());  
  33.     }  
  34.     @Override  
  35.     public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY)   
  36.     {  
  37.         Log.d("onScroll",e1.toString());  
  38.         return true;  
  39.     }  
  40.     @Override  
  41.     public boolean onDown(MotionEvent ev)   
  42.     {  
  43.         Log.d("onDownd",ev.toString());  
  44.         return true;  
  45.     }  
  46.     @Override  
  47.     public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY)   
  48.     {  
  49.         Log.d("d",e1.toString());  
  50.         Log.d("e2",e2.toString());  
  51.         return true;  
  52.     }  
  53. }</span>  

    1,在當前類中創建一個GestureDetector實例。

     private GestureDetector mGestureDetector;

    2,創建一個Listener來實時監聽當前面板操作手勢。

    private class LearnGestureListener extends GestureDetector.SimpleOnGestureListener                                                             

    3,在初始化時,將Listener實例關聯當前的GestureDetector實例。 

    mGestureDetector = new GestureDetector(this, new LearnGestureListener());

    4,利用onTouchEvent方法作爲入口檢測,通過傳遞MotionEvent參數來監聽操作手勢。

    mGestureDetector.onTouchEvent(event)


    第四種:

  1. <span style="font-family:SimSun;">private GestureDetector mGestureDetector;  
  2. @Override  
  3. public void onCreate(Bundle savedInstanceState)   
  4. {  
  5.     super.onCreate(savedInstanceState);  
  6.     mGestureDetector = new GestureDetector(thisnew MyGestureListener());  
  7. }  
  8. @Override  
  9. public boolean onTouchEvent(MotionEvent event)   
  10. {  
  11.     return mGestureDetector.onTouchEvent(event);   
  12. }  
  13. private class MyGestureListener extends GestureDetector.SimpleOnGestureListener  
  14. {  
  15.     @Override  
  16.     public boolean onSingleTapUp(MotionEvent ev)   
  17.     {  
  18.         Log.d("onSingleTapUp",ev.toString());  
  19.         return true;  
  20.     }  
  21.     @Override  
  22.     public void onShowPress(MotionEvent ev)   
  23.     {  
  24.         Log.d("onShowPress",ev.toString());  
  25.     }  
  26.     @Override  
  27.     public void onLongPress(MotionEvent ev)  
  28.     {  
  29.         Log.d("onLongPress",ev.toString());  
  30.     }  
  31.     …  
  32. }</span>  

    基本的內容就是創建一個GestureDetector的對象,傳入listener對象,在自己接收到的onTouchEvent中將event傳給GestureDetector進行分析,listener會回調給我們相應的動作。其中GestureDetector.SimpleOnGestureListener(Framework幫我們簡化了)是實現了上面提到的OnGestureListener和OnDoubleTapListener兩個接口的類,我們只需要繼承它並重寫其中我們關心的回調即可。

    最後,再提一下雙擊和三擊的識別過程:在第一次單擊down時,給Hanlder發送了一個延時300ms的消息,如果300ms裏,發生了第二次單擊的down事件,那麼,就認爲是雙擊事件了,並移除之前發送的延時消息。如果300ms後仍沒有第二次的down消息,那麼就判定爲SingleTapConfirmed事件(單擊事件)。三擊的判定和雙擊的判定類似,只是多了一次發送延時消息的過程。

  1. <pre></pre>  
  2. <pre></pre>  
  3. <pre></pre>  
  4. <pre></pre>  
  5. <pre></pre>  
  6. <pre></pre>  
  7. <pre></pre>  
  8.       
  9.         <div style="padding-top:20px">           
  10.             <p style="font-size:12px;">版權聲明:本文爲博主原創文章,未經博主允許不得轉載。</p>  
  11.         </div> 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章