【Android】GestureDetector類及其用法


當用戶觸摸屏幕的時候,會產生許多手勢,例如downupscrollfiling等等。

一般情況下,我們知道View類有個View.OnTouchListener內部接口,通過重寫他的onTouch(View v, MotionEvent event)方法,我們可以處理一些touch事件,但是這個方法太過簡單,如果需要處理一些復雜的手勢,用這個接口就會很麻煩(因為我們要自己根據用戶觸摸的軌跡去判斷是什么手勢)。

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

GestureDetector這個類對外提供了兩個接口:OnGestureListenerOnDoubleTapListener,還有一個內部類SimpleOnGestureListener

GestureDetector.OnDoubleTapListener接口:用來通知DoubleTap事件,類似於鼠標的雙擊事件。

1onDoubleTap(MotionEvent e):在雙擊的第二下Touch down時觸發 

2onDoubleTapEvent(MotionEvent e):通知DoubleTap手勢中的事件,包含downupmove事件(這里指的是在雙擊之間發生的事件,例如在同一個地方雙擊會產生DoubleTap手勢,而在DoubleTap手勢里面還會發生downup事件,這兩個事件由該函數通知);雙擊的第二下Touch downup都會觸發,可用e.getAction()區分。 

3onSingleTapConfirmed(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了還沒有滑動時觸發(與onDownonLongPress)比較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 1ACTION_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

 

SimpleOnGestureListenerGestureDetector提供給我們的一個更方便的響應不同手勢的類,這個類實現了上述兩個接口(但是所有的方法體都是空的),該類是static class,也就是說它實際上是一個外部類。程序員可以在外部繼承這個類,重寫里面的手勢處理方法。

 

方法步驟

第一種示例:

1,通過GestureDetector的構造方法可以將SimpleOnGestureListener對象傳遞進去,這樣GestureDetector能處理不同的手勢了。

public GestureDetector

(Context context, GestureDetector.OnGestureListener listener)

 

2,在OnTouchListeneronTouch方法中

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.SimpleOnGestureListenerFramework幫我們簡化了)是實現了上面提到的OnGestureListenerOnDoubleTapListener兩個接口的類,我們只需要繼承它並重寫其中我們關心的回調即可。

最后,再提一下雙擊和三擊的識別過程:在第一次單擊down時,給Hanlder發送了一個延時300ms的消息,如果300ms里,發生了第二次單擊的down事件,那么,就認為是雙擊事件了,並移除之前發送的延時消息。如果300ms后仍沒有第二次的down消息,那么就判定為SingleTapConfirmed事件(當然,此時用戶的手指應已完成第一次點擊的up過程)。三擊的判定和雙擊的判定類似,只是多了一次發送延時消息的過程。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM