- (一)Android事件分發(fā)機(jī)制 - View篇
- (二)Android事件分發(fā)機(jī)制 - ViewGroup篇
- (三)Android事件分發(fā)機(jī)制 - Activity篇
- (四)Android事件分發(fā)機(jī)制 - 總結(jié)篇
Android事件分發(fā)中三個重要方法:
public boolean dispatchTouchEvent(MotionEvent event)
dispatchTouchEvent
用來進(jìn)行事件的分發(fā)货抄。如果事件能夠傳遞給當(dāng)前的View
焕檬,那么此方法一定會被調(diào)用,返回結(jié)果表示是否分發(fā)當(dāng)前事件箱季。
public boolean onInterceptTouchEvent(MotionEvent ev)
onInterceptTouchEvent
是ViewGroup
提供的方法赂鲤,返回結(jié)果表示是否攔截當(dāng)前事件(默認(rèn)返回false
)噪径,如果當(dāng)前View
攔截了某個事件,那么在同一個事件序列當(dāng)中数初,此方法不會被再次調(diào)用找爱,
public boolean onTouchEvent(MotionEvent event)
onTouchEvent
在dispatchTouchEvent
方法中被調(diào)用,用來處理點擊事件泡孩,返回結(jié)果表示是否消耗當(dāng)前事件(默認(rèn)返回true
)车摄,如果不消耗,則在同一個事件序列中,當(dāng)前View
無法再次接受到事件吮播。
三個方法的分布情況:
閱讀Android事件分發(fā)的源代碼(6.0版本)
- 一個事件序列是指從手指觸摸屏幕開始变屁,到手指離開屏幕結(jié)束,這個過程中產(chǎn)生的一系列事件意狠。同一個事件序列是以
ACTION_DOWN
事件開始粟关,中間含有數(shù)量不定的ACTION_MOVE
事件,最終以ACTION_UP
事件結(jié)束环戈; - 事件傳遞的順序是:
Activity -> Window -> View
闷板,即事件總是先傳遞給Activity
,然后在傳遞給Window
院塞,最后在傳遞給View
遮晚,頂級View
接收到事件后,就會按照事件分發(fā)機(jī)制去分發(fā)事件拦止; - 事件的傳遞過程是由外向內(nèi)的鹏漆,即事件總是由父元素分發(fā)給子元素;
- 正常情況下创泄,一個事件序列只能被一個
View
攔截且消耗艺玲。一旦一個View
攔截了某次事件,那么同一個事件序列內(nèi)的所有事件都會直接交給它處理鞠抑,因此同一個事件序列中的事件不能分別由兩個View
同時處理饭聚,但是通過特殊手段可以做到,比如一個View
將本該自己處理的事件通過onTouchEvent強(qiáng)行傳遞給其他View
處理搁拙; - 某個
View
一旦開始處理事件秒梳,如果它不消耗ACTION_DOWN
事件,那么同一事件序列的其他事情都不會再交給它來處理箕速,并且事件將重新交給它的父容器去處理(調(diào)用父容器的onTouchEvent
方法)酪碘; - 某個
View
一旦開始處理事件,如果它消耗ACTION_DOWN
事件盐茎,但是不消耗其他類型事件兴垦,那么這個點擊事件會消失,父容器的onTouchEvent
方法不會被調(diào)用字柠,當(dāng)前view
依然可以收到后續(xù)的事件探越,但是這些事件最后都會傳遞給Activity
處理; - 點擊事件分發(fā)是到達(dá)頂級
View
后(一般是ViewGroup
)窑业,會首先調(diào)用dispatchTouchEvent
方法钦幔,其中它的onInterceptTouchEvent
方法如果返回true
,則會對事件傳遞進(jìn)行攔截常柄,事件由ViewGroup
處理鲤氢;如果onInterceptTouchEvent
方法返回false
搀擂,則代表不對事件進(jìn)行攔截(默認(rèn)返回false
),此時子View
中的dispatchTouchEvent
方法將被調(diào)用卷玉,到此哥倔,事件已經(jīng)由頂級View
傳遞給了下一層的View
,接下來的過程是一個遞歸循環(huán)的過程揍庄,和頂級View
事件分發(fā)過程是一致的,直到完成整個事件分發(fā)东抹。