Android 觸摸及手勢操作GestureDetector

來源:互聯網
上載者:User

Android 觸摸及手勢操作GestureDetector
 

現在的智能手機不敢說百分百的都是觸控螢幕,也應該是百分之九九以上為觸控螢幕了,觸控螢幕為我們操作無鍵盤、無滑鼠的手機系統帶來了很多的便利。當使用者觸控螢幕幕時會產生很多的觸摸事件,down、up、move等等。View類有個View.OnTouchListener內部介面,通過重寫他的onTouch(View v, MotionEvent event)方法,我們可以處理一些touch事件,如下:

 

public class MainActivity extends Activity {...// This example shows an Activity, but you would use the same approach if// you were subclassing a View.@Overridepublic boolean onTouchEvent(MotionEvent event){     int action = MotionEventCompat.getActionMasked(event);    switch(action) {        case (MotionEvent.ACTION_DOWN) :            Log.d(DEBUG_TAG,Action was DOWN);            return true;        case (MotionEvent.ACTION_MOVE) :            Log.d(DEBUG_TAG,Action was MOVE);            return true;        case (MotionEvent.ACTION_UP) :            Log.d(DEBUG_TAG,Action was UP);            return true;        case (MotionEvent.ACTION_CANCEL) :            Log.d(DEBUG_TAG,Action was CANCEL);            return true;        case (MotionEvent.ACTION_OUTSIDE) :            Log.d(DEBUG_TAG,Movement occurred outside bounds  +                    of current screen element);            return true;              default :             return super.onTouchEvent(event);    }      }


 

OnTouch提供的事件還是相對較簡單,如果需要處理一些複雜的手勢,用這個介面就會很麻煩,因為我們要根據使用者觸摸的軌跡去判斷是什麼手勢。Android sdk給我們提供了GestureDetector(Gesture:手勢Detector:識別)類,通過這個類我們可以識別很多的手勢。

 

public class GestureDetector extends Object

java.lang.Object

android.view.GestureDetector

GestureDetector屬於android.view包,android還提供了android.gesture包支援更多的手勢操作,以後我們會介紹到。官方的介紹中使用了GestureDetectorCompat處理手勢識別,為什麼使用GestureDetectorCompat替換了GestureDetector呢,官方的是這樣解釋的:

 

GestureDetectorCompat執行個體化有下面兩種方法:

 

GestureDetector類對外提供了兩個介面:OnGestureListener,OnDoubleTapListener,還有一個內部類SimpleOnGestureListener;SimpleOnGestureListener類是GestureDetector提供給我們的一個更方便的響應不同手勢的類,它實現了上述兩個介面,該類是static class,也就是說它實際上是一個外部類,我們可以在外部繼承這個類,重寫裡面的手勢處理方法。因此實現手勢識別有兩種方法,一種實現OnGestureListener介面,另一種是使用SimpleOnGestureListener類。

OnGestureListener有下面的幾個動作:

按下(onDown): 剛剛手指接觸到觸控螢幕的那一刹那,就是觸的那一下。

 

拋擲(onFling): 手指在觸控螢幕上迅速移動,並鬆開的動作。

 

長按(onLongPress): 手指按在持續一段時間,並且沒有鬆開。

 

滾動(onScroll): 手指在觸控螢幕上滑動。

 

按住(onShowPress): 手指按在觸控螢幕上,它的時間範圍在按下起效,在長按之前。

 

抬起(onSingleTapUp):手指離開觸控螢幕的那一刹那。

 

使用OnGestureListener介面,這樣需要重載OnGestureListener介面所有的方法,適合監聽所有的手勢,正如官方文檔提到的“Detecing All Supported Gestures”。

 

public class MainActivity extends Activity implements         GestureDetector.OnGestureListener,        GestureDetector.OnDoubleTapListener{    private static final String DEBUG_TAG = Gestures;    private GestureDetectorCompat mDetector;     // Called when the activity is first created.     @Override    public void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        // Instantiate the gesture detector with the        // application context and an implementation of        // GestureDetector.OnGestureListener        mDetector = new GestureDetectorCompat(this,this);        // Set the gesture detector as the double tap        // listener.        mDetector.setOnDoubleTapListener(this);    }    @Override     public boolean onTouchEvent(MotionEvent event){         this.mDetector.onTouchEvent(event);        // Be sure to call the superclass implementation        return super.onTouchEvent(event);    }    @Override    public boolean onDown(MotionEvent event) {         Log.d(DEBUG_TAG,onDown:  + event.toString());         return true;    }    @Override    public boolean onFling(MotionEvent event1, MotionEvent event2,             float velocityX, float velocityY) {        Log.d(DEBUG_TAG, onFling:  + event1.toString()+event2.toString());        return true;    }    @Override    public void onLongPress(MotionEvent event) {        Log.d(DEBUG_TAG, onLongPress:  + event.toString());     }    @Override    public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX,            float distanceY) {        Log.d(DEBUG_TAG, onScroll:  + e1.toString()+e2.toString());        return true;    }    @Override    public void onShowPress(MotionEvent event) {        Log.d(DEBUG_TAG, onShowPress:  + event.toString());    }    @Override    public boolean onSingleTapUp(MotionEvent event) {        Log.d(DEBUG_TAG, onSingleTapUp:  + event.toString());        return true;    }    @Override    public boolean onDoubleTap(MotionEvent event) {        Log.d(DEBUG_TAG, onDoubleTap:  + event.toString());        return true;    }    @Override    public boolean onDoubleTapEvent(MotionEvent event) {        Log.d(DEBUG_TAG, onDoubleTapEvent:  + event.toString());        return true;    }    @Override    public boolean onSingleTapConfirmed(MotionEvent event) {        Log.d(DEBUG_TAG, onSingleTapConfirmed:  + event.toString());        return true;    }}


這樣會造成有些手勢動作我們用不到,但是還要重載。SimpleOnGestureListener類的出現為我們解決了這個問題,如果你想“Detecting a Subset of Supported Gestures”,SimpleOnGestureListener是最好的選擇。

 

 

public class MainActivity extends Activity {     private GestureDetectorCompat mDetector;     @Override    public void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        mDetector = new GestureDetectorCompat(this, new MyGestureListener());    }    @Override     public boolean onTouchEvent(MotionEvent event){         this.mDetector.onTouchEvent(event);        return super.onTouchEvent(event);    }    class MyGestureListener extends GestureDetector.SimpleOnGestureListener {        private static final String DEBUG_TAG = Gestures;         @Override        public boolean onDown(MotionEvent event) {             Log.d(DEBUG_TAG,onDown:  + event.toString());             return true;        }        @Override        public boolean onFling(MotionEvent event1, MotionEvent event2,                 float velocityX, float velocityY) {            Log.d(DEBUG_TAG, onFling:  + event1.toString()+event2.toString());            return true;        }    }}


 

最後了我們也解釋兩個問題:

1、onTouchEvent中為什麼使用了MotionEventCompat,而不直接使用MotionEvent。因為MotionEventCompat使更多的Action適配到API 4。

2、Android的view怎麼使用手勢,方法如下:

 

 View myView = findViewById(R.id.my_view);         myView.setOnTouchListener(new OnTouchListener() {            public boolean onTouch(View v, MotionEvent event) {                // ... Respond to touch events                       this.mDetector.onTouchEvent(event);                return super.onTouchEvent(event);            }        });

 

 

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.