關於安卓事件分發的學習

View的兩個方法dispatchTouchEvent和onTouchEventhtml

 

探索andorid的事情傳遞以前應該知道android有兩個基礎的空間,view和viewGroup。view就是普通的控件,如button,Textview繼承自view,是沒有子佈局的。viewgroup表示能夠有子控件,如linearlayout,listview。android

事件即MotionEvent,主要有3中ide

(1)MotionEvent.ACTION_DOWN  按下View,是全部事件的開始函數

(2)MotionEvent.ACTION_MOVE   滑動事件佈局

(3)MotionEvent.ACTION_UP       與down對應,表示擡起ui

事件傳遞機制的目的是爲觸發view方法的點擊監聽和觸摸的監聽:spa

view.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            
        }
    });
}

 

view.setOnTouchListener(new View.OnTouchListener() {
    @Override
    public boolean onTouch(View v, MotionEvent event) {
        return false;
    }
});

onTouch監聽裏面的這個return false有大學問,下面就來研究下這個返回.net

 

view的事件傳遞有兩個函數,dispatchTouchEvent負責分發事件,在dispatch***裏又會調用onTouchEvent表示執行事件,或者說消費事件。事件傳遞的入口是View的dispatchTouchEvent()函數:orm

 

dispatchTouchEvent是觸摸事件的分發的,事件多數是從activity的dispatchTouchEvent開始執行super.htm

dispatchTouchEvent(ev),事件向下分發。

oninterceptTouchevent是viewgroup提供的方法,默認返回false,返回true表示攔截

onTouchEvent是view提供的方法,view中默認返回true,表示消費了此事件

View裏,有兩個回調函數 :

  1. public boolean dispatchTouchEvent(MotionEvent ev);    
  2. public boolean onTouchEvent(MotionEvent ev);   

 

 

ViewGroup裏,有三個回調函數 :

  1. public boolean dispatchTouchEvent(MotionEvent ev);    
  2. public boolean onInterceptTouchEvent(MotionEvent ev);    
  3. public boolean onTouchEvent(MotionEvent ev);  

 

 

在Activity裏,有兩個回調函數 :

 

  1. public boolean dispatchTouchEvent(MotionEvent ev);    
  2. public boolean onTouchEvent(MotionEvent ev);    

android中默認的狀況下是傳遞到view,傳遞過程是從父佈局到子佈局,也就是從acitivity到viewGroup到view的過程,

Android中事件傳遞過程(按箭頭方向)以下圖,圖片來自[qiushuiqifei],謝謝[qiushuiqifei]整理。

 觸摸事件是一連串ACTION_DOWN,ACTION_MOVE..MOVE…MOVE、最後ACTION_UP,觸摸事件還有ACTION_CANCEL事件。事件都是從ACTION_DOWN開始的,Activity的dispatchTouchEvent()首先接收到ACTION_DOWN,執行super.dispatchTouchEvent(ev),事件向下分發。

    dispatchTouchEvent()返回true,後續事件(ACTION_MOVE、ACTION_UP)會再傳遞,若是返回false,dispatchTouchEvent()就接收不到ACTION_UP、ACTION_MOVE。

 

下面的幾張圖參考自[eoe]

 

 

 

                                             圖1.ACTION_DOWN都沒被消費

 

                                

                                                                  圖2-1.ACTION_DOWN被View消費了

 

                

 

                                                   圖2-2.後續ACTION_MOVE和UP在不被攔截的狀況下都會去找VIEW

 

                              

                                                                    圖3.後續的被攔截了

 

                              

                                  圖4ACTION_DOWN一開始就被攔截

android中的Touch事件都是從ACTION_DOWN開始的:

單手指操做:ACTION_DOWN---ACTION_MOVE----ACTION_UP

多手指操做:ACTION_DOWN---ACTION_POINTER_DOWN---ACTION_MOVE--ACTION_POINTER_UP---ACTION_UP.

 

在ontouchevent中有一個performClick()裏面調用了onclick方法

1.也就是說點擊某個事件的時候會先執行dispatch***而後3個判斷都對上會執行ontouchEvent,若是一切順利,onTouchEvent會調用onclick方法

2.不管ondispatch**返回true或者ontouch返回true。事件都會被消費,不會再往下傳了。若是dispatch***在執行onTouch監聽的時候,onTouchEvent返回了true,那麼它也返回true,這個事件提早被onTouch消費掉了。就再也不執行onTouchEvent了,更別說onClick監聽了。

 

onTouch是個監聽方法,默認返回的是false,若是爲true,就表示事件消費,就不會去執行OnTouchEvent方法了

總結,會先執行父佈局的dispathc**方法。子佈局中dispathc*方法。而後看子佈局中的ontouch方法的返回類型,若是爲false。證實時間沒有被消費,就會執行子佈局的ontouchevent方法,在執行父佈局的ontouchevent方法。ontouch方法默認返回false,就證實touchenvent方法會被執行,若是不想讓他執行的話,就返回true,這樣ontouchEvent方法就不會執行 。最後纔會執行onclick方法。

相關文章
相關標籤/搜索