98
技術社區[雲棲]
淺析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