一 先看下過於GestureDetector類的表格
| 前三個為GestureDetector的內部接口類型,最后一個為實現了這三個接口的GestureDetector的靜態內部類 | 方法 | |
| OnGestureListener | onDown() onShowPress() onSingleTapup() onScroll() onLongPress() onFling() |
|
| OnDoubleTapListener | onSingleTapConfirmed() onDoubleTap() onDoubleTapEvent() |
|
| OnContextClickListener | onContextClick() | |
| SimpleOnGestureListener | 具備以上所有方法 | |
二 對上面的方法詳細介紹:
1.OnGestureListener,這個Listener監聽一些手勢,如單擊、滑動、長按等操作:
- onDown(MotionEvent e):用戶按下屏幕的時候的回調。
- onShowPress(MotionEvent e):用戶按下按鍵后100ms(根據Android7.0源碼)還沒有松開或者移動就會回調,官方在源碼的解釋是說一般用於告訴用戶已經識別按下事件的回調(我暫時想不出有什么用途,因為這個回調觸發之后還會觸發其他的,不像長按)。
- onLongPress(MotionEvent e):用戶長按后(好像不同手機的時間不同,源碼里默認是100ms+500ms)觸發,觸發之后不會觸發其他回調,直至松開(UP事件)。
- onScroll(MotionEvent e1, MotionEvent e2,float distanceX, float distanceY):手指滑動的時候執行的回調(接收到MOVE事件,且位移大於一定距離),e1,e2分別是之前DOWN事件和當前的MOVE事件,distanceX和distanceY就是當前MOVE事件和上一個MOVE事件的位移量。
- onFling(MotionEvent e1, MotionEvent e2, float velocityX,float velocityY):用戶執行拋操作之后的回調,MOVE事件之后手松開(UP事件)那一瞬間的x或者y方向速度,如果達到一定數值(源碼默認是每秒50px),就是拋操作(也就是快速滑動的時候松手會有這個回調,因此基本上有onFling必然有onScroll)。
- onSingleTapUp(MotionEvent e):用戶手指松開(UP事件)的時候如果沒有執行onScroll()和onLongPress()這兩個回調的話,就會回調這個,說明這是一個點擊抬起事件,但是不能區分是否雙擊事件的抬起。
2.OnDoubleTapListener,這個Listener監聽雙擊和單擊事件。
- onSingleTapConfirmed(MotionEvent e):可以確認(通過單擊DOWN后300ms沒有下一個DOWN事件確認)這不是一個雙擊事件,而是一個單擊事件的時候會回調。
- onDoubleTap(MotionEvent e):可以確認這是一個雙擊事件的時候回調。
- onDoubleTapEvent(MotionEvent e):onDoubleTap()回調之后的輸入事件(DOWN、MOVE、UP)都會回調這個方法(這個方法可以實現一些雙擊后的控制,如讓View雙擊后變得可拖動等)。
3.OnContextClickListener,很多人都不知道ContextClick是什么,我以前也不知道,直到我把平板接上了外接鍵盤——原來這就是鼠標右鍵。。。
- onContextClick(MotionEvent e):當鼠標/觸摸板,右鍵點擊時候的回調。
4.SimpleOnGestureListener,實現了上面三個接口的類,擁有上面三個的所有回調方法。
- 由於SimpleOnGestureListener不是抽象類,所以繼承它的時候只需要選取我們所需要的回調方法來重寫就可以了,非常方便,也減少了代碼量,符合接口隔離原則,也是模板方法模式的實現。而實現上面的三個接口中的一個都要全部重寫里面的方法,所以我們一般都是選擇SimpleOnGestureListener。
三 來個小栗子嘗嘗吧,這是一段可以Activity之間實現翻頁的的代碼
mGestureDetector = new GestureDetector(this, new GestureDetector.SimpleOnGestureListener() { @Override public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) { if (e1.getX() - e2.getX() > 0) { showNextPage(); } else { showPrePage(); } return super.onFling(e1, e2, velocityX, velocityY); } }); } // 監聽屏幕上響應的事件類型(按下,移動,抬起) @Override public boolean onTouchEvent(MotionEvent event) { // 通過手勢處理類,接收多種類型的事件,用作處理 mGestureDetector.onTouchEvent(event); return super.onTouchEvent(event); }
