-
觸摸事件的類型
Android中觸摸事件對應的類是MotionEvent類,事件的類型主要有如下三種情況
ACTION_DOWN:用戶手指的按下操作,一個按下事件標志著一個觸摸事件的開始
ACTION_MOVE:用戶手指按壓屏幕后,松開之前,如果移動的距離超過一定的閾值,那么會被判定為ACTION_MOVE操作,一般情況下手指輕微移動都會出發一系列的操作
ACTION_UP:用戶手指離開屏幕的操作,一次抬起標志著該事件的結束 -
事件傳遞的三個階段
分發:在Android中所有的事件分發對應著dispatchTouchEvent方法
QQ截圖20180516213123.png
在這個方法中,根據當前視圖的具體實現邏輯,來決定直接消費掉這個事件還是將該事件繼續分發給子視圖進行處理,方法返回值為true,表示事件被當前視圖消費掉,不再繼續分發事件,方法返回值為super.dispatchTouchEvent()則表示繼續分發該事件,如果當前視圖是ViewGroup及其子類,會調用onInterceptTouchEvent()方法來判定是否攔截該事件
攔截:事件的攔截對應著onInterceptTouchEvent(),此方法只在ViewGroup及其子類才有,Activity與View中是沒有該方法的
QQ截圖20180516214119.png
同理:該方法返回true,表示攔截該事件,不繼續分發給子視圖,同時交由自身的onTouchEvent()進行消費,返回super.onInterceptTouchEvent()表示不攔截該事件,需要繼續傳遞給子視圖
消費:事件的消費對應著onTouchEvent()方法
QQ截圖20180516214533.png
同理:該方法返回true,表示當前視圖可以處理該事件,事件將不會向上傳遞給福視圖,返回false表示當前視圖不處理該事件,事件將會傳遞給父視圖的onTouchEven()進行處理
經測試,我們得出以下結論
View的事件分發
從上面的結論可以得出,View事件的傳遞只關乎分發和消費,并沒有攔截的功能,那么兩個方法的返回值有可能存在以下三種情況
直接返回true
直接返回false
或者返回父類的同名方法
- 觸摸事件的傳遞流程是從dispatchTouchEvent()開始的,如果不進行人為的干預(也就是所默認返回父類的同名函數),則事件將會依照嵌套的層次從外層想內層傳遞,到達最內層的view時,就由它的onTouchEvent()進行處理,該方法能夠消費該事件,返回true,不能消費,則返回false,這時事件將會重新向外層傳遞,并由外層的onTouchEvent()進行處,以此類推
- 如果事件在內層傳遞過程中進行人為干預,事件處理的函數返回true,則會導致事件提前被消費掉,內層的view將不會收到該事件。
- View控件的事件觸發順序是先執行onTouch(),再最后執行onClick(),如果onTouch()返回true,則事件不會繼續傳遞,最后也不會調用onClick(),如果onTouch()返回false,則該事件繼續傳遞
ViewGroup的事件分發
- 觸摸事件的傳遞順序是由Activity到ViewGroup,再由ViewGroup遞歸傳遞給它的子view,
- ViewGroup通過onInterceptTouchEvent()對事件進行攔截,如果該方法返回true,則事件不會被繼續傳遞,如果返回false或者super.onInterceptTouchEvent,則事件被繼續傳遞給子view。
- 在子view中事件被消費后,ViewGroup將接受不到任何事件。