GestureDetector類及其用法

當用戶觸摸屏幕的時候,會產生許多手勢,例如down,up,scroll,filing等等。
一般情況下,我們知道View類有個View.OnTouchListener內部接口,通過重寫他的onTouch(View v, MotionEvent event)方法,我們可以處理一些touch事件,但是這個方法太過簡單,如果需要處理一些複雜的手勢,用這個接口就會很麻煩(因爲我們要自己根據用戶觸摸的軌跡去判斷是什麼手勢)。

Android sdk給我們提供了GestureDetector(Gesture:手勢Detector:識別)類,通過這個類我們可以識別很多的手勢,主要是通過他的onTouchEvent(event)方法完成了不同手勢的識別。雖然他能識別手勢,但是不同的手勢要怎麼處理,應該是提供給程序員實現的。


GestureDetector這個類對外提供了兩個接口:OnGestureListener,OnDoubleTapListener,還有一個內部類SimpleOnGestureListener。
GestureDetector.OnDoubleTapListener接口:用來通知DoubleTap事件,類似於鼠標的雙擊事件。
1,onDoubleTap(MotionEvent e):在雙擊的第二下,Touch down時觸發 。
2,onDoubleTapEvent(MotionEvent e):通知DoubleTap手勢中的事件,包含down、up和move事件(這裏指的是在雙擊之間發生的事件,例如在同一個地方雙擊會產生DoubleTap手勢,而在DoubleTap手勢裏面還會發生down和up事件,這兩個事件由該函數通知);雙擊的第二下Touch down和up都會觸發,可用e.getAction()區分。 

   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);
             }



第三種示例


package com.example.gesturedetector;

import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.GestureDetector;
import android.view.MotionEvent;

public class MainActivity extends Activity {

	private GestureDetector mGestureDetector;

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		mGestureDetector = new GestureDetector(this, new LearnGestureListener());
	}

	@Override
	public boolean onTouchEvent(MotionEvent event) {
		if (mGestureDetector.onTouchEvent(event))
			return true;
		else
			return false;
	}

	class LearnGestureListener 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());
		}

		@Override
		public boolean onScroll(MotionEvent e1, MotionEvent e2,
				float distanceX, float distanceY) {
			Log.d("onScroll", e1.toString());
			return true;
		}

		@Override
		public boolean onDown(MotionEvent ev) {
			Log.d("onDownd", ev.toString());
			return true;
		}

		@Override
		public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
				float velocityY) {
			Log.d("d", e1.toString());
			Log.d("e2", e2.toString());
			return true;
		}
	}
}

重點
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過程)。三擊的判定和雙擊的判定類似,只是多了一次發送延時消息的過程。

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