Android開發(fā)中時常會遇到需要自定義View事件處理行為的場景,每次遇到,都會去查找一下講解事件分發(fā)原理的一些文章,看完雖然也能找到解決方案,但始終有種似是而非的感覺。于是我想稍稍整理下我對事件分發(fā)設(shè)計原理的理解。
一、基礎(chǔ)概念
????事件:系統(tǒng)對用戶的觸摸動作封裝而成的一個對象。包括id,類型,位置等信息
? ? 事件序列:同一個手指產(chǎn)生的一系列的事件
? ? view樹,從父view到子view的一個樹狀結(jié)構(gòu)
二、系統(tǒng)機制
? ? 1dispatchTouchEvent為處理事件入口,感覺handle更貼切一些,分發(fā)有點誤導(dǎo)
? ? 2dispatchTouchEvent方法中包括處理事件傳遞的邏輯以及當(dāng)前view的處理事件的邏輯,如果成功處理了該事件,則返回true。成功處理包含自己處理了,或者自己的子view處理了。
? ? 3事件傳遞邏輯主要圍繞事件對象,處理事件的子view對象,事件傳遞打斷機制展開
? ? ? ? ? ? 1onInterceptTouchEvent方法,攔截的含義是不再向下傳遞該事件序列當(dāng)前和之后的事件;再詳細(xì)點是包括,不再嘗試查找可能處理事件的子view,以及發(fā)送cancel事件給之前處理了該事件序列的事件處理者,并且攔截的事件繼續(xù)由自己的事件處理方法onTouchEvent處理。
? ? 4如果經(jīng)過以上處理邏輯沒有成功處理該事件,則交給當(dāng)前view自己的事件處理邏輯處理,事件處理邏輯在OnTouchEvent方法中實現(xiàn)。
? ? 5事件一旦處理成功,立刻終止事件處理流程。
三、注意點
? ? 1攔截邏輯:如果是down事件或者事件序列的處理者不為空,則調(diào)用onInterruptTouchEvent來決定是否打斷傳遞;否則,必定攔截傳遞動作(也就是如果不是down事件,也沒有子view在之前的down事件中成功處理過該down事件,這樣處理合理省事)
? ? 2實現(xiàn)時盡量不要改寫dispatchTouchEvent方法,而是通過改寫onIntercept方法或者onTouchEvent或者設(shè)置onTouchListener方法來實現(xiàn)事件處理需求。