淺析GestureDetector
原文:https://www.cnblogs.com/xirihanlin/archive/2010/12/29/1920356.html
最近在研究場景切換的動畫效果,其中需要用到三連擊的動作觸發。三連擊,即點三下屏幕,但意義上是雙擊效果。 因此,我需要研究如何識別三連擊的動作。
我們知道,一般的View隻能響應點擊(Click)和長按(LongPress)事件。這是因為View裏隻暴露了這些listener給我們使用。而實質上,View是在onTouchEvent(MotionEvent event)裏對用戶的動作做了一定的分析,從而通知我們是發生了點擊還是長按等事件。
View裏提供的回調在我描述的場景裏,並不能滿足要求。因此,GestureDetector出場了。我需要對其啃透才能寫出自己的ActionDetector。
GestureDetector類可以幫助我們分析用戶的動作,和View的onTouchEvent的處理方式差不多,但分析的動作類型更加細致,以下是它的回調接口:
public interface OnGestureListener { // Touch down時觸發, e為down時的MotionEvent boolean onDown(MotionEvent e); // 在Touch down之後一定時間(115ms)觸發,e為down時的MotionEvent void onShowPress(MotionEvent e); // Touch up時觸發,e為up時的MotionEvent boolean onSingleTapUp(MotionEvent e); // 滑動時觸發,e1為down時的MotionEvent,e2為move時的MotionEvent boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY); // 在Touch down之後一定時間(500ms)觸發,e為down時的MotionEvent void onLongPress(MotionEvent e); // 滑動一段距離,up時觸發,e1為down時的MotionEvent,e2為up時的MotionEvent boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY); } public interface OnDoubleTapListener { // 完成一次單擊,並確定沒有二擊事件後觸發(300ms),e為down時的MotionEvent boolean onSingleTapConfirmed(MotionEvent e); // 第二次單擊down時觸發,e為第一次down時的MotionEvent boolean onDoubleTap(MotionEvent e); // 第二次單擊down,move和up時都觸發,e為不同時機下的MotionEvent boolean onDoubleTapEvent(MotionEvent e); }
有了這麼多的回調消息,我們就能更加方便的對用戶的動作進行響應,那麼,這個類如何使用呢?以下是使用該類的一個範例:
private GestureDetector mGestureDetector; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); mGestureDetector = new GestureDetector(this, new MyGestureListener()); } @Override public boolean onTouchEvent(MotionEvent event) { return mGestureDetector.onTouchEvent(event); } class MyGestureListener extends GestureDetector.SimpleOnGestureListener{ @Override public boolean onSingleTapUp(MotionEvent ev) { Log.d("onSingleTapUp",ev.toString()); return true; } @Override public void onShowPress(MotionEvent ev) { Log.d("onShowPress",ev.toString()); } @Override public void onLongPress(MotionEvent ev) { Log.d("onLongPress",ev.toString()); } … }
基本的內容就是創建一個GestureDetector的對象,傳入listener對象,在自己接收到的onTouchEvent中將event傳給GestureDetector進行分析,listener會回調給我們相應的動作。其中GestureDetector.SimpleOnGestureListener(Framework幫我們簡化了)是實現了上麵提到的OnGestureListener和OnDoubleTapListener兩個接口的類,我們隻需要繼承它並重寫其中我們關心的回調即可。
最後,再提一下雙擊和三擊的識別過程:在第一次單擊down時,給Hanlder發送了一個延時300ms的消息,如果300ms裏,發生了第二次單擊的down事件,那麼,就認為是雙擊事件了,並移除之前發送的延時消息。如果300ms後仍沒有第二次的down消息,那麼就判定為SingleTapConfirmed事件(當然,此時用戶的手指應已完成第一次點擊的up過程)。三擊的判定和雙擊的判定類似,隻是多了一次發送延時消息的過程,有意思吧~~~嘿嘿~~~
最後更新:2017-04-02 06:52:05