編輯:關於Android編程
”觸摸手勢“發生在用戶放置一個或者多個手指在觸摸屏上的時候,然後你的應用程序翻譯這個觸摸模型作為一個特別的手勢。手勢檢測有相應的兩個階段:
采集關於觸摸事件的數據。
翻譯這個數據去查看它是否符合你的應用程序支持的任何手勢的標准。
在這個課程中的例子使用了GestureDetectorCompat和MotionEventCompat類。這些類都在Support Library中。你應該在可能提供兼容性,運行Android1.6和更高的設備中使用支持庫類。注意MotionEventCompat不是MotionEvent類的一個替代。當然,它提供了靜態實體方法,你傳遞給你的MotionEvent對象,為了獲取和事件相關的期望的動作。
—————————————————————————————————————————————————————————————————
當用戶放置一個或者多個手指在屏幕上的時候,觸發在獲取觸摸事件的視圖中的onTouchEvent()方法。對於每個序列的觸摸事件(position.pressure,size,addition of another finder,ect.)最終確定為一個手勢,onTouchEvent()方法被觸發幾次。
手勢從用戶第一次觸摸屏幕的時候開始,隨著系統跟蹤用戶手指的位置而繼續,最後以捕獲用戶手指離開屏幕的最後事件結束。整個交互中,MotionEvent被分傳遞給onTouchEvent()方法,提供了每個交互的詳細說明。你的應用程序能使用通過MotionEvent提供的數據,來確定一個手勢是否發生。
為了截取在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); } }你然後在這些事件中能做自己的處理,來確定是否發生了一個手勢。對於自定義手勢這種處理是你必須做的。然而,如果你的應用程序使用通常的手勢,例如雙擊,長按,點,等等,你可以充分利用GestureDetector類。GestureDetector不處理個人的觸摸事件,使檢測通常的手勢對於你變得簡單。這個在下面Detect Gestures中被討論。
作為onTouchEvent()方法供替代的選擇,你能使用setOnTouchListener()方法給任何View附加一個View.onTouchListener對象。這使的監聽觸摸事件,但沒有子類化一個已存在View成為可能。例如:
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(),等等。你能結合上面描述的onTouchEvent()方法使用GestureDetector類。
當你實例化一個GestureDectectorCompat對象的時候,它使用的一個參數是一個實現了GestureDectector.onGestureListener接口的類。當一個特定的觸摸事件發生的時候,GestureDetector.onGestureListener通知用戶。為了使你的GestureDetector對象獲取這個事件變成可能,你覆蓋這個View或者Activity的onTouchEvent()方法,並傳遞所可被觀察到的事件給這個檢測者實例。
在下面的代碼塊中,從各個on
運行下面的代碼塊,感受一下當你和觸摸屏交互的時候,操作是如何被觸發的,和每個觸摸事件的MetionEventneo內容。你將會認識到簡單的交互生成了如此多的數據。
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; } }
如果你僅僅想處理一些手勢,你能繼承GestureDetector.SimpleOnGestureListener替代實現GestureDectector.onGestureListener接口。
GestureDetector.SimpleOnGestureListener提供了所有on
不論你是否使用GestureDectector.onGestureListener,實現一個onDown()方法的最好實踐是返回ture。這個是因為所有的手勢都是以onDown()消息開始的。如果你從onDown()方法返回false,如GestureDectector.SimpleOnGestureListener默認行為,這個系統假設你不會理睬其余的手勢,並且其它GestureDectector.onGestureListener的方法從來不會調用。這可能在你的應用程序中導致意外的問題。你能從onDown()方法返回false的唯一時間是,如果你真的想不理睬整個手勢。
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、頂部單張圖片左右拖拉滑動;2、帶指引;3、僅滑動頂
在上一篇《Android仿微信滑動彈出編輯、刪除菜單效果、增加下拉刷新功能》裡,已經帶著大家學習如何使用SwipeMenuListView這一開源庫實現滑動列表彈出菜單,
Android開發過程中,經常遇到一個項目需要重復的定義相同樣式的標題欄,Android相繼推出了actionBar, toolBar, 相信有用到的朋友也會遇到一些不如
總結: asset目錄下文件: 稱為原生文件,這類文件在被打包成apk文件時是不會進行壓縮的,不會自動生成R文件的ID 訪問: 獲取路徑: f