在我們使用手機的時候,會與應(yīng)用進行各種交互行為韭畸,每次滑動白魂,點擊都是一種觸摸事件,在Android中有如下一些觸摸事件
- ACTION_DOWN = 0槽片,手觸摸到屏幕時觸發(fā)
- ACTION_UP = 1何缓,手按完屏幕,離開屏幕時出發(fā)
- ACTION_MOVE = 2还栓,手在屏幕上滑動時觸發(fā)
- ACTION_CANCEL =3碌廓,接收到觸摸事件中任一事件后,其后續(xù)的事件被攔截無法接收剩盒,則觸發(fā)cancel
- ACTION_OUTSIDE = 4谷婆,手滑到屏幕外或者View之外,一般不由該View進行處理辽聊,而是通過Window.Callback進行回調(diào)
如何分發(fā)觸摸事件
大致分發(fā)流程
Activity收到事件纪挎,并傳給小弟處理(DecorView也是一個ViewGroup)
Activity -> PhoneWindow -> ViewGroup -> ... -> View
若小弟處理不了,則回傳給Activity
Activity <- PhoneWindow <- ViewGroup <- ... <- View
對于事件跟匆,Android中有三個方法來處理它
- dispatchTouchEvent() -- 分發(fā)事件异袄,將事件傳遞出去
- onInterceptTouchEvent() -- 攔截事件,子View或下一層級的就收不到該事件
- onTouchEvent() -- 處理事件
Activity贾铝,ViewGroup隙轻,View中是否含有上述方法
方法 | Activty | ViewGroup | View |
---|---|---|---|
dispatchTouchEvent() | √ | √ | √ |
onInterceptTouchEvent() | × | √ | × |
onTouchEvent() | √ | √ | √ |
由上表可見,Activity和View都沒有攔截事件的方法
因為Activiy處于事件分發(fā)的頂端垢揩,若攔截了玖绿,View就無法做出響應(yīng),影響用戶體驗
而View處于最底層叁巨,再攔截事件已經(jīng)沒有意義斑匪,要么就處理掉事件,要么就不做處理
分發(fā)流程的比喻
- Activity:老板
- RootView:經(jīng)理
- ChildView:員工
在方法中進行打印log锋勺,默認調(diào)用父類方法(即返回值均為false)蚀瘸,布局如下
Tips:操作方式為點擊ChildView,只有Down庶橱,沒有Up的行為贮勃,模擬器上鼠標按住即可
dispatchTouchEvent: ---------ViewActivity--老板:接到活啦
dispatchTouchEvent: ---------RootView-----經(jīng)理:我也接到活啦
onInterceptTouchEvent: -----RootView-----經(jīng)理:偷懶,丟給員工做
dispatchTouchEvent: ---------ChildView----員工:狗經(jīng)理又來壓榨我了苏章,收到任務(wù)
onTouchEvent: -----------------ChildView----員工:發(fā)現(xiàn)做不了寂嘉,告知經(jīng)理
onTouchEvent: -----------------RootView----經(jīng)理:報告老板奏瞬,做不了啊泉孩!
onTouchEvent: -----------------ViewActivity-老板:報告客戶硼端,這活我不做了
ChildView中onTouchEvent為true時,即員工發(fā)現(xiàn)這個活自己能做寓搬,則經(jīng)理和老板就不用處理啦
dispatchTouchEvent: ---------ViewActivity
dispatchTouchEvent: ---------RootView
onInterceptTouchEvent: -----RootView
dispatchTouchEvent: ---------ChildView
onTouchEvent: -----------------ChildView
RootView中onInterceptTouchEvent為true時珍昨,經(jīng)理有B數(shù),知道員工做不了句喷,就不告知員工了镣典,此時員工不需要處理,只要經(jīng)理上報回老板即可
dispatchTouchEvent: -------ViewActivity
dispatchTouchEvent: -------RootView
onInterceptTouchEvent: ---RootView
onTouchEvent: ---------------RootView
onTouchEvent: ---------------ViewActivity
總結(jié)
對于 dispatchTouchEvent
- Activity
- ture:事件被消耗脏嚷,不會傳遞給經(jīng)理骆撇,就是不理會客戶的活
- false:接活瞒御,并傳下去讓下一層處理
- ViewGroup(RootView)
- 情況跟Activity類似父叙,要么不做,要么傳給小弟
- View
- true:回調(diào)onTouchEvent()
- false:不回調(diào)
簡而言之就是true時會回調(diào)onTouchEvent()肴裙,false則不回調(diào)
對于 onInterceptTouchEvent
攔截后(返回值為true)趾唱,下一層不會回調(diào)dispatchTouchEvent(),而是自己處理蜻懦,更不會回調(diào)下一層的onTouchEvent()
對于 onTouchEvent
false的話就會告知上層甜癞,讓上層進行處理
而true的話,自己做完后就行宛乃,不必匯報上層