1. 程式人生 > >Touch事件傳遞流程、事件分發中的onTouch 和onTouchEvent 有什麼區別,又該如何使用?

Touch事件傳遞流程、事件分發中的onTouch 和onTouchEvent 有什麼區別,又該如何使用?

Touch事件傳遞流程
1.Touch事件型別
 Touch事件被封裝成MotionEvent,使用者當前的touch事件主要型別有:
       ACTION_DOWN: 表示使用者開始觸控
     ACTION_MOVE: 表示使用者在移動(手指或者其他)
     ACTION_UP:表示使用者擡起了手指
     ACTION_CANCEL:表示手勢被取消了
     ACTION_OUTSIDE: 表示使用者觸碰超出了正常的UI邊界.
     ACTION_POINTER_DOWN:有一個非主要的手指按下了.
     ACTION_POINTER_UP:一個非主要的手指擡起來了


2.Touch事件元資料
     touch事件的元資料主要包括:touch的位置、手指的個數、touch事件的時間。一個touch手勢被定義為以ACTION_DOWN開始和以 ACTION_UP結束。
3.事件傳遞流程:
Android 中與 Touch 事件相關的方法包括:dispatchTouchEvent(MotionEvent ev)、onInterceptTouchEvent(MotionEvent ev)、onTouchEvent(MotionEvent ev);

能夠響應這些方法的控制元件包括:ViewGroup、View、Activity。

方法與控制元件的對應關係如下:

  Touch 事件相關方法 方法功能 ViewGroup View Activity
  public boolean dispatchTouchEvent(MotionEvent ev) 事件分發 Yes Yes Yes
  public boolean onInterceptTouchEvent(MotionEvent ev) 事件攔截 Yes No No
  public boolean onTouchEvent(MotionEvent ev) 事件響應 Yes Yes Yes

區別:

        onTouch方法優先順序比onTouchEvent高,會先觸發。假如onTouch方法返回false,會接著觸發onTouchEvent,反之onTouchEvent方法不會被呼叫。內建諸如click事件的實現等等都基於onTouchEvent,假如onTouch返回true,這些事件將不會被觸發。

使用:

1、onTouch()方法:

  onTouch方式是View的OnTouchListener介面中定義的方法。當一個View綁定了OnTouchListener後,當有Touch事件觸發時,就會呼叫onTouch方法。

testBt.setOnTouchListener(new 
View.OnTouchListener() { @Override public boolean onTouch(View view, MotionEvent motionEvent) { switch (motionEvent.getAction()) { case MotionEvent.ACTION_DOWN://0 Log.e("TAG", " onTouch按住"); break; case MotionEvent.ACTION_UP://1 Log.e("TAG", " onTouch擡起"); break; case MotionEvent.ACTION_MOVE://2 Log.e("TAG", " onTouch移動"); break; } //事件分發 //1setOnTouchListener單獨使用的時候返回值需要true,這樣才能保證移動的時候獲取相應的監聽,而非一次監聽(即只有按下事件) //返回false,表示沒有被處理,將向父View傳遞。只能監聽到view"按下"事件,"移動""擡起"都不能監聽到。因為down事件未結束 //返回true,消耗此事件,表示正確接收並處理,不在分發。"按下""擡起""移動"都能監聽到了 //2setOnTouchListenersetOnClickListener同時使用時, //返回true,事件被onTouch消耗掉了,因而不會在繼續向下傳遞。只能監聽"按下""擡起""移動",不能監聽到"點選"//返回false,"按下""擡起""移動""點選"都能監聽 //onTouch是優先於onClick的,並且執行了兩次,一次是ACTION_DOWN,一次是ACTION_UP(可能還會有多次ACTION_MOVE)因此事件傳遞的順序是先經過OnTouch,再傳遞給onClick return false; } });

2、onTouchEvent()方法:

  onTouchEvent方法時過載的Activity的方法 重寫了Acitivity的onTouchEvent方法後,當螢幕有Touch事件時,此方法就會被呼叫。

@Override
public boolean onTouchEvent(MotionEvent event) {
    switch (event.getAction()) {
        case MotionEvent.ACTION_DOWN://0
Log.e("TAG", " onTouchEvent 按住");
            break;
        case MotionEvent.ACTION_UP://1
Log.e("TAG", " onTouchEvent 擡起");
            break;
        case MotionEvent.ACTION_MOVE://2
Log.e("TAG", " onTouchEvent 移動");
            break;
}
    return super.onTouchEvent(event);
}