Android官方开发文档Training系列课程中文版:手势处理之监测通用手势
原文地址:http://android.xsoftlab.net/training/gestures/index.html
引言
這節課將會學習如何讓用戶通過觸摸手勢與APP產生交互。Android提供了許多相關API來幫助你創建、檢測手勢。
盡管APP不應該將觸摸手勢作為基本的輸入特性,但是觸摸手勢可以使APP快速提高可操作性與吸引力。
為了提供一種一貫的,直觀的用戶體驗,APP應當使用Android通用的觸摸手勢標準。
檢測通用手勢
當用戶將一根或者多根手指放置在觸摸屏上時就會產生觸摸事件,應用程序需要將這次的觸摸行為解釋為一種特別的手勢事件。下面是檢測手勢事件相應的執行步驟:
- 1.收集觸摸事件的相關數據。
- 2.解釋這些數據,查看是否有程序所支持的任何標準手勢。
收集數據
當用戶將手指放在屏幕上時,這會回調相應View的onTouchEvent()方法。
手勢開始于用戶第一次觸到屏幕時,接下來系統會追蹤手指的位置,最后結束于手指離開屏幕時的最后一次事件。在這整個交互過程中,MotionEvent對象由onTouchEvent()方法分發,并提供了每個事件的相關詳細信息。APP可以使用MotionEvent對象所提供的數據來檢查是否有APP所關心的事件發生。
為Activity或View捕獲觸摸事件
為了攔截Activity或者View的觸摸事件,需要重寫它們的onTouchEvent()回調方法。
下面的代碼使用getActionMasked()方法來提取event參數中含有的用戶執行行為。它提供了你所關心的原始數據:
public class MainActivity extends Activity { ... // This example shows an Activity, but you would use the same approach if // you were subclassing a View. @Override public 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);} }使單個View捕獲觸摸事件
除了onTouchEvent()方法之外,你還可以使用View.OnTouchListener來監聽觸摸手勢。這使得不重寫onTouchEvent()還可以監聽觸摸事件成為了可能:
View myView = findViewById(R.id.my_view); myView.setOnTouchListener(new OnTouchListener() {public boolean onTouch(View v, MotionEvent event) {// ... Respond to touch events return true;} });要注意所創建的監聽器在ACTION_DOWN事件時返回的false。如果你這么做了,那么監聽器接下來對于ACTION_MOVE及ACTION_UP等一系列事件將不會調用。這是因為ACTION_DOWN事件是所有觸摸事件的起點。
如果你創建了一個自定義View,你可以像上面描述的那樣重寫onTouchEvent()方法。
檢測手勢
Android提供了GestureDetector類來檢測通用手勢。這些手勢包括onDown(), onLongPress(), onFling()等等。你可以將GestureDetector與onTouchEvent()結合使用。
檢查所有支持的手勢
當你在實例化GestureDetectorCompat對象時,其中一個參數需要實現GestureDetector.OnGestureListener接口。
GestureDetector.OnGestureListener接口的作用是:在指定的觸摸事件發生時通知用戶。為了使GestureDetector對象可以接收到觸摸事件,你需要重寫View或者Activity的onTouchEvent()方法,并將所有的事件傳遞給GestureDetector對象。
在下面的代碼中,由onTouchEvent()方法所返回的true代表了你要負責處理這次的觸摸事件。返回值false則代表你想忽略這次事件,直到這次的觸摸事件被處理完畢。
運行下面的代碼找找感覺:當你在觸摸屏上操作時每種行為是如何被觸發的;以及每一種觸摸事件的MotionEvent對象的內容是什么。你將會意識到一個簡單的觸摸事件是由多么龐大的數據處理產生的。
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. @Overridepublic 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.OnGestureListenermDetector = 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 implementationreturn super.onTouchEvent(event);}@Overridepublic boolean onDown(MotionEvent event) { Log.d(DEBUG_TAG,"onDown: " + event.toString()); return true;}@Overridepublic boolean onFling(MotionEvent event1, MotionEvent event2, float velocityX, float velocityY) {Log.d(DEBUG_TAG, "onFling: " + event1.toString()+event2.toString());return true;}@Overridepublic void onLongPress(MotionEvent event) {Log.d(DEBUG_TAG, "onLongPress: " + event.toString()); }@Overridepublic boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX,float distanceY) {Log.d(DEBUG_TAG, "onScroll: " + e1.toString()+e2.toString());return true;}@Overridepublic void onShowPress(MotionEvent event) {Log.d(DEBUG_TAG, "onShowPress: " + event.toString());}@Overridepublic boolean onSingleTapUp(MotionEvent event) {Log.d(DEBUG_TAG, "onSingleTapUp: " + event.toString());return true;}@Overridepublic boolean onDoubleTap(MotionEvent event) {Log.d(DEBUG_TAG, "onDoubleTap: " + event.toString());return true;}@Overridepublic boolean onDoubleTapEvent(MotionEvent event) {Log.d(DEBUG_TAG, "onDoubleTapEvent: " + event.toString());return true;}@Overridepublic boolean onSingleTapConfirmed(MotionEvent event) {Log.d(DEBUG_TAG, "onSingleTapConfirmed: " + event.toString());return true;} }檢測支持手勢的子集
如果你只是想處理幾種手勢,那么你可以繼承GestureDetector.SimpleOnGestureListener接口。
GestureDetector.SimpleOnGestureListener提供了對于onTouchEvent()方法所有的實現,這樣你只用重寫你所關心的方法。比如說,在下面的代碼中創建了一個繼承GestureDetector.SimpleOnGestureListener接口的類,然后重寫了它的onFling()方法及onDown()方法。
無論你是否使用了GestureDetector.OnGestureListener接口,最佳的練習點在于重寫了返回true的onDown()方法。這是因為所有的手勢都是從onDown()開始的。如果在onDown()方法中返回了false,就像GestureDetector.SimpleOnGestureListener默認做的那樣,那么系統會認為你想忽略余下的手勢,并且GestureDetector.OnGestureListener接口的其它方法都不會被調用。這會在APP內埋下一個潛在的不易察覺的問題。如果你確認你要忽略整個手勢流,那么onDown()中的結果false將是唯一的機會。
public class MainActivity extends Activity { private GestureDetectorCompat mDetector; @Overridepublic 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"; @Overridepublic boolean onDown(MotionEvent event) { Log.d(DEBUG_TAG,"onDown: " + event.toString()); return true;}@Overridepublic boolean onFling(MotionEvent event1, MotionEvent event2, float velocityX, float velocityY) {Log.d(DEBUG_TAG, "onFling: " + event1.toString()+event2.toString());return true;}} }總結
以上是生活随笔為你收集整理的Android官方开发文档Training系列课程中文版:手势处理之监测通用手势的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 情报领域因果推理智能项目概览:以DAPA
- 下一篇: Android官方开发文档Trainin