android GestureDetector 手勢基礎

來源:互聯網
上載者:User

標籤:android   io   os   ar   java   sp   div   art   on   



1. 當使用者觸控螢幕幕的時候,會產生許多手勢,例如down,up,scroll,filing等等,我們知道View類有個View.OnTouchListener內部介面,通過重寫他的onTouch(View v, MotionEvent event)方法,我們可以處理一些touch事件,但是這個方法太過簡單,如果需要處理一些複雜的手勢,用這個介面就會很麻煩(因為我們要自己根據使用者觸摸的軌跡去判斷是什麼手勢)Android sdk給我們提供了GestureDetector(Gesture:手勢Detector:識別)類,通過這個類我們可以識別很多的手勢,主要是通過他的onTouchEvent(event)方法完成了不同手勢的識別。雖然他能識別手勢,但是不同的手勢要怎麼處理,應該是提供給程式員實現的,因此這個類對外提供了兩個介面:OnGestureListener,OnDoubleTapListener,還有一個內部類SimpleOnGestureListener,SimpleOnGestureListener類是GestureDetector提供給我們的一個更方便的響應不同手勢的類,這個類實現了上述兩個介面(但是所有的方法體都是空的),該類是static class,也就是說它實際上是一個外部類。程式員可以在外部繼承這個類,重寫裡面的手勢處理方法。
通過GestureDetector的構造方法可以將SimpleOnGestureListener對象傳遞進去,這樣GestureDetector能處理不同的手勢了。2. 具體用法:2.1 DefaultGestureListener.java 
  1. private class DefaultGestureListener extends SimpleOnGestureListener{
  2.         @Override
  3.         public boolean onSingleTapUp(MotionEvent e) {
  4.             return false;
  5.         }
  6.         @Override
  7.         public void onLongPress(MotionEvent e) {
  8.         }
  9.         /**
  10.          * @param e1 The first down motion event that started the scrolling.
  11.            @param e2 The move motion event that triggered the current onScroll.
  12.            @param distanceX The distance along the X axis(軸) that has been scrolled since the last call to onScroll. This is NOT the distance between e1 and e2.
  13.            @param distanceY The distance along the Y axis that has been scrolled since the last call to onScroll. This is NOT the distance between e1 and e2.
  14.                        無論是用手拖動view,或者是以拋的動作滾動,都會多次觸發 ,這個方法在ACTION_MOVE動作發生時就會觸發 參看GestureDetector的onTouchEvent方法源碼
  15.          * */
  16.         @Override
  17.         public boolean onScroll(MotionEvent e1, MotionEvent e2,
  18.                 float distanceX, float distanceY) {
  19.             return false;
  20.         }
  21.         /**
  22.          * @param e1 第1個ACTION_DOWN MotionEvent 並且只有一個
  23.          * @param e2 最後一個ACTION_MOVE MotionEvent 
  24.          * @param velocityX X軸上的移動速度,像素/秒  
  25.          * @param velocityY Y軸上的移動速度,像素/秒
  26.          * 這個方法發生在ACTION_UP時才會觸發 參看GestureDetector的onTouchEvent方法源碼
  27.          * 
  28.          * */
  29.         @Override
  30.         public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
  31.                 float velocityY) {
  32.             return false;
  33.         }
  34.         @Override
  35.         public void onShowPress(MotionEvent e) {
  36.         }
  37.         @Override
  38.         public boolean onDown(MotionEvent e) {
  39.             return false;
  40.         }
  41.         @Override
  42.         public boolean onDoubleTap(MotionEvent e) {
  43.             return false;
  44.         }
  45.         @Override
  46.         public boolean onDoubleTapEvent(MotionEvent e) {
  47.             return false;
  48.         }
  49.         /**
  50.          * 這個方法不同於onSingleTapUp,他是在GestureDetector確信使用者在第一次觸控螢幕幕後,沒有緊跟著第二次觸控螢幕幕,也就是不是“雙擊”的時候觸發
  51.          * */
  52.         @Override
  53.         public boolean onSingleTapConfirmed(MotionEvent e) {
  54.             return false;
  55.         }
  56.     }
複製代碼2.2   public GestureDetector (Context context, GestureDetector.OnGestureListener listener)     //通過構造方法將手勢響應交給手勢識別類2.3   在OnTouchListener的onTouch方法中
  1. private OnTouchListener gestureTouchListener = new OnTouchListener() {
  2.         @Override
  3.         public boolean onTouch(View v, MotionEvent event) {
  4.             return gDetector.onTouchEvent(event);
  5.         }
  6.     };
複製代碼ok,到此為止就結束了.3.案例:Res.java
  1. package com.android;
  2. import android.app.Activity;
  3. import android.os.Bundle;
  4. import android.util.Log;
  5. import android.view.GestureDetector;
  6. import android.view.MotionEvent;
  7. import android.view.View;
  8. import android.widget.Button;
  9. public class Res extends Activity implements View.OnTouchListener {
  10.     Button btn = null;
  11.     private GestureDetector mGestureDetector = null;
  12.     /** Called when the activity is first created. */
  13.     @Override
  14.     public void onCreate(Bundle savedInstanceState) {
  15.         super.onCreate(savedInstanceState);
  16.         setContentView(R.layout.main);
  17.         btn = (Button) findViewById(R.id.button);
  18.         btn.setOnTouchListener(this);
  19.         mGestureDetector = new GestureDetector(this, new LearnGestureListener());
  20.     }
  21.     public boolean onTouch(View view, MotionEvent event) {
  22.         return mGestureDetector.onTouchEvent(event);
  23.     }
  24.     class LearnGestureListener extends GestureDetector.SimpleOnGestureListener {
  25.         @Override
  26.         public boolean onSingleTapUp(MotionEvent ev) {
  27.             Log.d("DEBUG","onSingleTapUp");
  28.             return true;
  29.         }
  30.         @Override
  31.         public void onShowPress(MotionEvent ev) {
  32.             Log.d("DEBUG","onShowPress");
  33.         }
  34.         @Override
  35.         public void onLongPress(MotionEvent ev) {
  36.             Log.d("DEBUG","onLongPress");
  37.         }
  38.         @Override
  39.         public boolean onScroll(MotionEvent e1, MotionEvent e2,
  40.                 float distanceX, float distanceY) {
  41.             Log.d("DEBUG","onScroll");
  42.             return true;
  43.         }
  44.         @Override
  45.         public boolean onDown(MotionEvent ev) {
  46.             Log.d("DEBUG","onDownd");
  47.             return true;
  48.         }
  49.         @Override
  50.         public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
  51.                 float velocityY) {
  52.             Log.d("DEBUG","onFling");
  53.             return true;
  54.         }
  55.         public boolean onDoubleTap(MotionEvent event){
  56.             Log.d("DEBUG","onDoubleTap");
  57.             return true;
  58.         }
  59.     }
  60. }
複製代碼4.遇到的問題:
1. onFling(***)無法觸發
通過設定 mListView.setLongClickable(true);即可(我處理的是ListView的手勢事件),只有這樣,view才能夠處理不同於Tap(輕觸)的hold(即ACTION_MOVE,或者多個ACTION_DOWN),我們同樣可以通過layout定義中的android:longClickable來做到這一點。
2. 使用者長按手機螢幕,就會觸發長按事件,離開螢幕時,就會觸發up事件,但是SimpleOnGestureListener沒有對longPress事件的up事件對外提供介面
解決辦法:
類似於這樣,截獲up事件,因為所有的都是有OnTouchListener 先獲得,然後傳遞給SimpleOnGestureListener的,這裡有一點必須要注意:
截獲到up事件,我們進行了處理後,必須要將這個事件再交給SimpleOnGestureListener處理,雖然我們只截獲長按事件的up,但是SimpleOnGestureListener對於長按事件的up也做了一些處理,只是沒有對外提供介面。做了什麼處理: 
  1. if (mInLongPress) {
  2.                 mHandler.removeMessages(TAP);
  3.                 mInLongPress = false;
  4. }
複製代碼如果不交給SimpleOnGestureListener處理,那麼單擊動作也會觸發onLongPress方法。
  1. private OnTouchListener gestureTouchListener = new OnTouchListener() {
  2.         @Override
  3.         public boolean onTouch(View v, MotionEvent event) {
  4.             switch (event.getAction()) {
  5.             case MotionEvent.ACTION_DOWN:
  6.                 return gDetector.onTouchEvent(event);
  7.            case MotionEvent.ACTION_UP:
  8.                 MyGesture.FlagInfo info = mGesture.getFlagInfo();
  9.                 if(info.isConnected==true){
  10.                     int firstVisiblePosition = mListView.getFirstVisiblePosition();
  11.                     View view = mListView.getChildAt(info.position-firstVisiblePosition);
  12.                     if(view!=null){
  13.                         view.setBackgroundResource(R.drawable.listitem_background_blue);
  14.                         info.isConnected = false;
  15.                     }
  16.                 }
  17.                 return gDetector.onTouchEvent(event);
  18.             case MotionEvent.ACTION_MOVE:
  19.                 return gDetector.onTouchEvent(event);
  20.             }
  21.             return false;
  22.         }
  23.     };
複製代碼總結:1. 點擊螢幕上的某項的執行流程 有兩種情況,一種是時間很短,一種時間稍長
時間很短:onDown——–》onSingleTapUp——–》onSingleTapConfirmed
時間稍長:onDown——–》onShowPress——》onSingleTapUp——–》onSingleTapConfirmed
2. 長按事件
onDown——–》onShowPress——》onLongPress
3.拋:手指觸動螢幕後,稍微滑動後立即鬆開
onDown—–》onScroll—-》onScroll—-》onScroll—-》………—–>onFling
4.拖動
onDown——》onScroll—-》onScroll——》onFiling
注意:有的時候會觸發onFiling,但是有的時候不會觸發,個人理解是人的動作不標準所致。

android GestureDetector 手勢基礎

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.