Android 手勢&觸摸事件詳解

在剛開始學Android的時候,就覺得Google的文檔不咋樣,在研究手勢時,更加的感覺Google的文檔寫得實在是太差了。很多常量,屬性和方法,居然連個描述都沒有。
沒有描述也就罷了,但是OnGestureListener裏手勢這麼多,它也沒有一個介紹說明,在沒有進行不斷才嘗試之前,誰能搞懂onLongPress和onShowPress,
onScroll和onFling的關係與差別嗎?Google真的需要在文檔方面做一次大手術了。不過好在經過鄙人不斷反覆的嘗試。從個人的角度爲這幾個手勢動作做出了定義。

 

按下(onDown): 剛剛手指接觸到觸摸屏的那一剎那,就是觸的那一下。 
拋擲(onFling): 手指在觸摸屏上迅速移動,並鬆開的動作。 
長按(onLongPress): 手指按在持續一段時間,並且沒有鬆開。 
滾動(onScroll): 手指在觸摸屏上滑動。 
按住(onShowPress): 手指按在觸摸屏上,它的時間範圍在按下起效,在長按之前。 
擡起(onSingleTapUp):手指離開觸摸屏的那一剎那。 

 

除了這些定義之外,鄙人也總結了一點算是經驗的經驗吧,在這裏和大家分享一下。

任何手勢動作都會先執行一次按下(onDown)動作。 
長按(onLongPress)動作前一定會執行一次按住(onShowPress)動作。 
按住(onShowPress)動作和按下(onDown)動作之後都會執行一次擡起(onSingleTapUp)動作。 
長按(onLongPress)、滾動(onScroll)和拋擲(onFling)動作之後都不會執行擡起(onSingleTapUp)動作。

Android識別觸摸屏手勢使得用戶體驗大大提高。在View類中有個View.OnTouchListener內部接口,通過重寫他的onTouch(View v, MotionEvent event)方法,我們可以處理一些簡單的touch事件,但是這個方法並不能識別手勢,如果需要處理一些複雜的手勢,用這個接口就會很麻煩(因爲我們要自己根據用戶觸摸的軌跡去判斷是什麼手勢)。好在Android爲我們提供了GestureDetector類,通過它,我們可以輕鬆的進行手勢識別。下面我做一個簡要地介紹。
一.GestureDetector簡介
1.組成
GestureDetector類用來識別觸摸屏的各種手勢,它包含了兩個接口和一個內部類:
接口:
OnGestureListener:用來監聽手勢事件(6種)。
OnDoubleTapListener:用來監聽雙擊事件。
內部類:
SimpleOnGestureListener:用來監聽所有的手勢。實際上它實現了上述兩個接口,不過方法體是空的,需要我們自己寫。我們可以繼承這個類,重寫裏面的方法進行手勢處理。
2.構造
GestureDetector gestureDetector=new GestureDetector(GestureDetector.OnGestureListener listener);
GestureDetector gestureDetector=new GestureDetector(Context context,GestureDetector.OnGestureListener listener);
GestureDetector gestureDetector=new GestureDetector(Context context,GestureDetector.SimpleOnGestureListener listener);
3.方法
(1)onTouchEvent(MotionEvent ev) 分析捕捉到的觸摸事件觸發相應的回調函數
(2)setIsLongpressEnabled(boolean isLongpressEnabled) 設置“長按”是否可用
(3)setOnDoubleTapListener(GestureDetector.OnDoubleTapListener onDoubleTapListener) 設置雙擊監聽器
4.使用
流程:
首先,系統捕捉屏幕的觸摸事件(onTouchListener),這時還未涉及具體手勢,只是簡單地捕捉到觸摸。
接着,在onTouch()方法中調用GestureDetector的onTouchEvent()方法,將捕捉到的MotionEvent交給GestureDetector來處理
最後,還需要實現抽象方法。
實現:
(1)在Activity中創建GestureDetector實例gestureDetector。
(2)可根據需要選擇:
重寫OnGestureListener並通過構造函數傳入gestureDetector
重寫OnDoubleTapListener並通過GestureDetector.setOnDoubleTapListener方法傳入gestureDetector
重寫SimpleOnGestureListener並通過構造函數傳入gestureDetector
(3)重寫Activity的onTouchEvent方法,將所有的觸摸事件交給gestureDetector來處理
@Override
public boolean onTouchEvent(MotionEvent event) {
return gestureDetector.onTouchEvent(event);
}
二.onGestureListener
1.onGestureListener識別6種手勢,分別是:
(1) onDown(MotionEvent e):down事件;
(2) onSingleTapUp(MotionEvent e):一次點擊up事件;
(3) onShowPress(MotionEvent e):down事件發生而move或則up還沒發生前觸發該事件;
(4) onLongPress(MotionEvent e):長按事件;
(5) onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY):滑動手勢事件;
(6) onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY):在屏幕上拖動事件。
這裏我需要囉嗦在網上搜到的關於onFling和onScroll的一點區別。
onFling()是甩,這個甩的動作是在一個MotionEvent.ACTION_UP(手指擡起)發生時執行,而onScroll(),只要手指移動就會執行。他不會執行MotionEvent.ACTION_UP。onFling通常用來實現翻頁效果,而onScroll通常用來實現放大縮小和移動。

2.重寫

	OnGestureListener onGestureListener=new OnGestureListener(){
 		@Override
 		public boolean onDown(MotionEvent e) {
 		return false;
	 }
 	@Override
 	public boolean onFling(MotionEvent e1, MotionEvent e2,
	 	float velocityX, float velocityY) {
 		return false;
	 }
 	@Override
 	public boolean onLongPress(MotionEvent e) {
 		return false;
 	}
 	@Override
 	public boolean onScroll(MotionEvent e1, MotionEvent e2,
 		float distanceX, float distanceY) {
 			return false;
 	}
 	@Override
	 public void onShowPress(MotionEvent e) {

	}
	 @Override
 	public boolean onSingleTapUp(MotionEvent e) {
 		return false;
	 }
 }



可以根據需要,在函數裏添加具體的處理方法.之後通過構造函數傳入GestureDetector即可。
GestureDetector gestureDetector=new GestureDetector(this,onGestureListener);
二.OnDoubleTapListener
1.OnDoubleTapListener是用來檢測鼠標雙擊事件的。需要實現的抽象方法有:
(1) onDoubleTap(MotionEvent e):雙擊事件。
(2) onDoubleTapEvent(MotionEvent e):雙擊間隔中還發生其他的動作。通知DoubleTap手勢中的事件,包含down、up和move事件
(這裏指的是在雙擊之間發生的事件,例如在同一個地方雙擊會產生DoubleTap手勢,而在DoubleTap手勢裏面還會發生down和up事件,這兩個事件由該函數通知);
(3) onSingleTapConfirmed(MotionEvent e):單擊事件。用來判定該次點擊是SingleTap而不是DoubleTap,如果連續點擊兩次就是DoubleTap手勢,
如果只點擊一次,系統等待一段時間後沒有收到第二次點擊則判定該次點擊爲SingleTap而不是DoubleTap,然後觸發SingleTapConfirmed事件。
關於onSingleTapConfirmed和onSingleTapUp的一點區別: OnGestureListener有這樣的一個方法onSingleTapUp,和onSingleTapConfirmed容易混淆。
二者的區別是:onSingleTapUp,只要手擡起就會執行,而對於onSingleTapConfirmed來說,如果雙擊的話,則onSingleTapConfirmed不會執行。

 

2.重寫

	OnDoubleTapListener onDoubleTapListener new OnDoubleTapListener() {
	 @Override
 	public boolean onSingleTapConfirmed(MotionEvent e) {
 		return false;
 	}
 	@Override
 	public boolean onDoubleTapEvent(MotionEvent e) {
 		return false;
 	}
	 @Override
 	public boolean onDoubleTap(MotionEvent e) {
 		return false;
	 }
 )

 

可以根據需要,在函數裏添加具體的處理方法.,之後通過setOnDoubleTapListener傳入GestureDetector即可。
gestureDetector.setOnDoubleTapListener(onDoubleTapListener) ;
三.SimpleOnGestureListener
SimpleOnGestureListener是GestureDetector類的一個內部類,該類是static class,也就是說它實際上是一個外部類。可以在外部繼承這個類,重寫裏面的手勢處理方法。
1.SimpleOnGestureListener實際上實現了OnGestureListener 和OnDoubleTapListener,所以它可以完成以上提到的所有手勢識別(9種),如上介紹。
2.重寫

 

	public class simpleOnGestureListener extends SimpleOnGestureListener {

	@Override
 	public boolean onDoubleTap(MotionEvent e) {
 		return super.onDoubleTap(e);
	 }
 	@Override
 	public boolean onDoubleTapEvent(MotionEvent e) {
 		return super.onDoubleTapEvent(e);
 	}
	 @Override
 	public boolean onDown(MotionEvent e) {
 		return super.onDown(e);
 	}
 	@Override
 	public boolean onFling(MotionEvent e1, MotionEvent e2, float x,
 	float y) {
 		return super.onFling(e1, e2, x, y);
 	}
 	@Override
 	public void onLongPress(MotionEvent e) {
 		super.onLongPress(e);
 	}
	 @Override
 	public boolean onScroll(MotionEvent e1, MotionEvent e2, float x,
 	float y) {
 		return super.onScroll(e1, e2, x, y);
 	}
	 @Override
	 public void onShowPress(MotionEvent e) {
		 super.onShowPress(e);
 	}
 	@Override
	 public boolean onSingleTapConfirmed(MotionEvent e) {
 		return super.onSingleTapConfirmed(e);
	 }
	 @Override
 	public boolean onSingleTapUp(MotionEvent e) {
 		return super.onSingleTapUp(e);
 	}
 }


 

可以根據需要,在函數裏添加具體的處理方法,之後通過構造函數傳入GestureDetector即可。
GestureDetector gestureDetector=new GestureDetector(this,simpleOnGestureListener );
四.另一種思路
要實現捕捉屏幕手勢,除了在Activity中創建gestureDetector外,還有一種思路:構建一個Overlay,這個Overlay實現OnGestureListener接口,使其維護自己的GestureDetector。
在主視圖上添加這個Overlay,並傳入相應的listener,即可實現捕捉手勢的功能。

 

轉載,原文地址:http://blog.csdn.net/song_shi_chao/article/details/8224742


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章