當用戶觸摸屏幕的時候,會產生許多手勢,例如down,up,scroll,filing等等。 程序員
通常狀況下,咱們知道View類有個View.OnTouchListener內部接口,經過重寫他的onTouch(View v, MotionEvent event)方法,咱們能夠處理一些touch事件,可是這個方法太過簡單,若是須要處理一些複雜的手勢,用這個接口就會很麻煩(由於咱們要本身根據用戶觸摸的軌跡去判斷是什麼手勢)。 ide
Android sdk給咱們提供了GestureDetector(Gesture:手勢Detector:識別)類,經過這個類咱們能夠識別不少的手勢,主要是經過他的onTouchEvent(event)方法完成了不一樣手勢的識別。雖然他能識別手勢,可是不一樣的手勢要怎麼處理,應該是提供給程序員實現的。 函數
GestureDetector這個類對外提供了兩個接口:OnGestureListener,OnDoubleTapListener,還有一個內部類SimpleOnGestureListener。 this
GestureDetector.OnDoubleTapListener接口:用來通知DoubleTap事件,相似於鼠標的雙擊事件。 spa
1,onDoubleTap(MotionEvent e):在雙擊的第二下,Touch down時觸發 。 orm
2,onDoubleTapEvent(MotionEvent e):通知DoubleTap手勢中的事件,包含down、up和move事件(這裏指的是在雙擊之間發生的事件,例如在同一個地方雙擊會產生DoubleTap手勢,而在DoubleTap手勢裏面還會發生down和up事件,這兩個事件由該函數通知);雙擊的第二下Touch down和up都會觸發,可用e.getAction()區分。 對象
3,onSingleTapConfirmed(MotionEvent e):用來斷定該次點擊是SingleTap而不是DoubleTap,若是連續點擊兩次就是DoubleTap手勢,若是隻點擊一次,系統等待一段時間後沒有收到第二次點擊則斷定該次點擊爲SingleTap而不是DoubleTap,而後觸發SingleTapConfirmed事件。這個方法不一樣於onSingleTapUp,他是在GestureDetector確信用戶在第一次觸摸屏幕後,沒有緊跟着第二次觸摸屏幕,也就是否是「雙擊」的時候觸發 繼承
GestureDetector.OnGestureListener接口:用來通知普通的手勢事件,該接口有以下六個回調函數:
1. onDown(MotionEvent e):down事件;
2. onSingleTapUp(MotionEvent e):一次點擊up事件;在touch down後又沒有滑動 接口
(onScroll),又沒有長按(onLongPress),而後Touchup時觸發。 事件
點擊一下很是快的(不滑動)Touchup:
onDown->onSingleTapUp->onSingleTapConfirmed
點擊一下稍微慢點的(不滑動)Touchup:
onDown->onShowPress->onSingleTapUp->onSingleTapConfirmed
3. onShowPress(MotionEvent e):down事件發生而move或則up還沒發生前觸發該
事件;Touch了尚未滑動時觸發(與onDown,onLongPress)比較onDown只要Touch down必定馬上觸發。而Touchdown後過一會沒有滑動先觸發onShowPress再是onLongPress。因此Touchdown後一直不滑動
按照onDown->onShowPress->onLongPress這個順序觸發。
4. onLongPress(MotionEvent e):長按事件;Touch了不移動一直Touch down時觸發
5. onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY):滑動手
勢事件;Touch了滑動一點距離後,在ACTION_UP時纔會觸發
參數: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):在屏幕上
拖動事件。不管是用手拖動view,或者是以拋的動做滾動,都會屢次觸發,這個方法在ACTION_MOVE動做發生時就會觸發
拋:手指觸動屏幕後,稍微滑動後當即鬆開
onDown-----》onScroll----》onScroll----》onScroll----》………----->onFling
拖動
onDown------》onScroll----》onScroll------》onFiling
SimpleOnGestureListener類是GestureDetector提供給咱們的一個更方便的響應不一樣手勢的類,這個類實現了上述兩個接口(可是全部的方法體都是空的),該類是static class,也就是說它其實是一個外部類。程序員能夠在外部繼承這個類,重寫裏面的手勢處理方法。
方法步驟
第一種示例:
1,經過GestureDetector的構造方法能夠將SimpleOnGestureListener對象傳遞進去,這樣GestureDetector能處理不一樣的手勢了。
public GestureDetector
(Context context, GestureDetector.OnGestureListener listener)
2,在OnTouchListener的onTouch方法中
private OnTouchListener gestureTouchListener = new OnTouchListener() {
public boolean onTouch(View v, MotionEvent event) {
return gDetector.onTouchEvent(event);
}
};
第二種示例:
使用方法
private GestureDetector mGestureDetector;
mGestureListener = new BookOnGestureListener();
構造出來mGestureDetector = new GestureDetector(mGestureListener);
class BookOnGestureListener implements OnGestureListener {
同時要public boolean onTouchEvent(MotionEvent event) {
mGestureListener.onTouchEvent(event);
}
第三種示例代碼
代碼:
01.private GestureDetector mGestureDetector;
02.@Override
03.public void onCreate(Bundle savedInstanceState) {
04. super.onCreate(savedInstanceState);
05. mGestureDetector = new GestureDetector(this, new LearnGestureListener());
06.}
07.@Override
08.public boolean onTouchEvent(MotionEvent event) {
09. if (mGestureDetector.onTouchEvent(event))
10. return true;
11. else
12. return false;
13.}
14.class LearnGestureListener extends GestureDetector.SimpleOnGestureListener{
15. @Override
16. public boolean onSingleTapUp(MotionEvent ev) {
17. Log.d("onSingleTapUp",ev.toString());
18. return true;
19. }
20. @Override
21. public void onShowPress(MotionEvent ev) {
22. Log.d("onShowPress",ev.toString());
23. }
24. @Override
25. public void onLongPress(MotionEvent ev) {
26. Log.d("onLongPress",ev.toString());
27. }
28. @Override
29. public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
30. Log.d("onScroll",e1.toString());
31. return true;
32. }
33. @Override
34. public boolean onDown(MotionEvent ev) {
35. Log.d("onDownd",ev.toString());
36. return true;
37. }
38. @Override
39. public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
40. Log.d("d",e1.toString());
41. Log.d("e2",e2.toString());
42. return true;
43. }
44.}
1,在當前類中建立一個GestureDetector實例。
private GestureDetector mGestureDetector;
2,建立一個Listener來實時監聽當前面板操做手勢。
class LearnGestureListener extends GestureDetector.SimpleOnGestureListener
3,在初始化時,將Listener實例關聯當前的GestureDetector實例。
mGestureDetector = new GestureDetector(this, new LearnGestureListener());
4,利用onTouchEvent方法做爲入口檢測,經過傳遞MotionEvent參數來監聽操做手勢。
1.mGestureDetector.onTouchEvent(event)
第四種示例代碼
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過程)。三擊的斷定和雙擊的斷定相似,只是多了一次發送延時消息的過程。