---恢復內容開始---android
1.Touch事件傳遞機制框架
過程有點兒相似於棧, ViewGroup的子類有都繼承它的如下3個方法:ide
public boolean dispatchTouchEvent(MotionEvent event); //消息分發, 至關於在一個函數中調用其餘函數函數
public boolean onInterceptTouchEvent(MotionEvent event); // 攔截消息this
public boolean onTouchEvent(MotionEvent event); // 觸屏處理, 若是完成處理則返回true, 至關於break直接退出消息處理,若是沒有完成處理則返回false, 返回到分發消息給它的View控件的onTouchEvent()繼續進行遞歸處理.制定返回到消息來源處spa
消息往下分發稱爲隧道方式, 觸屏消息在子視圖中沒有處理完傳遞給上層控件,稱爲冒泡方式.code
2.區別onTouch() 和 onTouchEvent()xml
onTouch(): 定義在接口OnTouchListener中, 綁定觸屏監聽器後覆寫這個方法實現自定義觸屏行爲對象
onTouchEvent(): Activity 中的方法, 當屏幕有觸摸事件時調用這個方法, 若是一直按着屏幕,就會一直循環調用,個人電腦上大概幾十毫秒調用一次,不過這個不用管. 固然, onTouch()方法也會在你一直按着綁定的控件的時候一直循環調用.blog
3.onTouchEvent()處理的消息
onTouchEvent()方法是從Activity中繼承下來的, 因此只須要在Activity中覆寫就能夠了, 它處理如下3種消息
1) 屏幕按下: MotionEvent.ACTION_DOWN
2) 從屏幕上釋放: MotionEvent.ACTION_UP
3) 在屏幕上移動: MotionEvent.ACTION_MOVE
1 @Override 2 public boolean onTouchEvent(MotionEvent event) { 3 int[] events = { 4 MotionEvent.ACTION_DOWN, 5 MotionEvent.ACTION_MOVE, 6 MotionEvent.ACTION_UP, 7 MotionEvent.ACTION_CANCEL, 8 MotionEvent.ACTION_OUTSIDE, 9 MotionEvent.ACTION_POINTER_DOWN, 10 MotionEvent.ACTION_POINTER_UP, 11 MotionEvent.EDGE_TOP, 12 MotionEvent.EDGE_BOTTOM, 13 MotionEvent.EDGE_LEFT, 14 MotionEvent.EDGE_RIGHT 15 }; 16 String[] szEvent = { 17 "MotionEvent.ACTION_DOWN", 18 "MotionEvent.ACTION_MOVE", 19 "MotionEvent.ACTION_UP", 20 "MotionEvent.ACTION_CANCEL", 21 "MotionEvent.ACTION_OUTSIDE", 22 "MotionEvent.ACTION_POINTER_DOWN", 23 "MotionEvent.ACTION_POINTER_UP", 24 "MotionEvent.EDGE_TOP", 25 "MotionEvent.EDGE_BOTTOM", 26 "MotionEvent.EDGE_LEFT", 27 "MotionEvent.EDGE_RIGHT" 28 }; 29 for(int i=0;i<events.length;++i){ 30 if(events[i] == event.getAction()){ 31 Log.v(TAG,szEvent[i]); 32 break; 33 } 34 } 35 return super.onTouchEvent(event); 36 }
將上面的方法覆蓋Activity的方法便可, 值得注意的是,MOVE事件會在你點擊釋放過程當中觸發, 並且觸發屢次! 因此在手勢識別過程部分函數參數會只記錄最後一個MOVE事件
4.手勢識別: android.view.GestureDetector類 + OnGestureListener接口
裏面有不少方法,覆寫以後能夠實現多種觸屏效果, 增長用戶體驗
使用GestureDetector對象,爲這個對象添加一個監聽器,並覆寫方法. 這個對象能夠做爲Activity的屬性, 固然也就是最這個Activity進行手勢解析了.而後再覆寫Activity的onTouchEvent方法, 對觸屏事件進行監聽便可.
1 private GestureDetector gestureDetector = new GestureDetector(new GestureDetector.OnGestureListener() { 2 @Override 3 public boolean onDown(MotionEvent e) { 4 // 按下屏幕的時候 5 Toast.makeText(MainActivity.this,"onDown",Toast.LENGTH_SHORT).show(); 6 Log.v(TAG,"onDown"); 7 return false; 8 } 9 10 @Override 11 /** 12 * 點擊了屏幕, 可是沒有移動和彈起動做. 與onDown的區別: 13 * onDown():一旦按下屏幕,就嘗試onDown事件 14 * onShowPress(): onDown事件產生後,一段時間內沒有移動和彈起(先產生了onDown事件) 15 * 16 */ 17 public void onShowPress(MotionEvent e) { 18 Log.v(TAG,"onShowPress"); 19 Toast.makeText(MainActivity.this,"onShowPress",Toast.LENGTH_SHORT).show(); 20 } 21 22 @Override 23 /** 24 * 輕擊觸摸屏和彈起,這個過程當中若是產生了onLongPress,onScroll 和 onFling事件,就不會產生onSingleTabUp事件 25 */ 26 public boolean onSingleTapUp(MotionEvent e) { 27 Log.v(TAG,"onSingleTabUp"); 28 Toast.makeText(MainActivity.this, "onSingleTagUp", Toast.LENGTH_SHORT).show(); 29 return false; 30 } 31 32 @Override 33 /** 34 * 滾動事件, 當在屏幕上迅速移動,會產生onScroll,由ACTION_MOVE產生 35 * @param: distanceX: 距離上次產生onScroll事件後, X軸的移動距離 36 */ 37 public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) { 38 Log.v(TAG,"onScroll"); 39 Toast.makeText(MainActivity.this, "onScroll", Toast.LENGTH_SHORT).show(); 40 return false; 41 } 42 43 @Override 44 public void onLongPress(MotionEvent e) { 45 Log.v(TAG,"onLongPress"); 46 Toast.makeText(MainActivity.this, "onLongPress", Toast.LENGTH_SHORT).show(); 47 } 48 49 @Override 50 /** 51 * @param: e1: 第一個ACTION_DOWN MotionEvent 52 * @param: e2: 最後一個ACTION_MOVE MotionEvent 53 * @param: velocityX: X軸上的移動速度 px/s 54 * @param: velocityY: Y軸上的移動速度 55 */ 56 public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) { 57 Log.v(TAG,"onFling"); 58 Toast.makeText(MainActivity.this, "onFling", Toast.LENGTH_SHORT).show(); 59 60 return false; 61 } 62 }); 63 64 @Override 65 public boolean onTouchEvent(MotionEvent event) { 66 Log.v(TAG,"onTouchEvent"); 67 if(gestureDetector.onTouchEvent(event)){ 68 return true; 69 }else{ 70 return super.onTouchEvent(event); //未完成處理交給上層控件 71 }
72 }
5.處理鍵盤事件
覆寫Activity的onKeyDown()便可,有的須要在AndroidManifest.xml文件中添加權限...
1 public boolean onKeyUp(int keyCode, KeyEvent event) { 2 switch (keyCode){ 3 case KeyEvent.KEYCODE_HOME: //好像說再也不支持了,須要修改框架源碼實現,有點兒複雜,期待新發現 4 Log.v(TAG,"HOME up"); 5 break; 6 case KeyEvent.KEYCODE_BACK: 7 Log.v(TAG,"BACK up"); 8 break; 9 case KeyEvent.KEYCODE_DPAD_LEFT: 10 Log.v(TAG,"Left up"); 11 break; 12 } 13 // return true; 14 return super.onKeyUp(keyCode, event); 15 }