Android Touch 事件總結

---恢復內容開始---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 }
相關文章
相關標籤/搜索