Android「打工人」:誰說事件分發很簡單的,我被這個給問哭了!

南方吳彥祖_藍斯發表於2020-11-16

今天這週上班第一天給大家娛樂一下,給大家講講事件分發,你可能會一笑:“別搞我呀,事件分發誰不知道呀。”

但是,今天的內容,可能真的有你不知道的。

注意: 如果你對事件分發原理並不是太瞭解,那麼需要先對事件分發有足夠的瞭解,最後再進行後續的閱讀。

下面開始正文,因為這個問題是與同事間交流產生,所以本文以對話形式呈現。

主角:

小 A,小 B。

小 A:B 啊,你給我言簡意賅的講講事件分發的流程。

小 B:好嘞。

“事件分發是針對一次手勢的過程,這個手勢包含一次 ACTION_DOWN,多次 ACTION_MOVE,和一次 ACTION_UP”,在 ACTION_DOWN 的時候來決定本次事件的“TargetView”,該 View 會決定這次事件分發的事件流向。

父控制元件可以在 ACTION_DOWN或者 targetView不為空的情況下,進行攔截,如果攔截了 targetView 的事件,會給它發一個 ACTION_CANCEL。

小 A:回答的可以呀,我來考你幾個問題。

小 B:儘管來。

小 A:你說一次事件分發過程中會有多次ACTION_POINT_DOWN嗎?

小 B內心:這不是送分題麼,看樣子小 A 兄弟對於多指這塊不太熟悉呀,這都能做為問題。

小 B:當然可以,多指的時候,你按下第一個手指,再按下第二個手指ACTION_POINTER_DOWN就來了。

你可以看看 ViewPager,ScrollView 這些官方類原始碼,都有多指的處理。

小 A:鬼魅一笑,然後那我再問你,一次事件分發過程中,可能會有多次ACTION_DOWN嗎?

小 B:等等,如果我答對了,一瓶可樂。

小 A:好。

小 B:沒有,只有你第一個手指按下才是 ACTION_DOWN,從第二個開始都是ACTION_POINTER_DOWN,當然了前提是你自己不修改 dispatchTouchEvent 分發邏輯哈,改了可不算,是不是要去買可樂了。

小 A:好,最後我再問你一個具體的問題,一個 LinearLayout 內部有兩個 Button,當我第一個手指按在第一個 Button 上,第二個手指按在第二個 Button 上,這兩個 Button哪個會收到 ACTION_DOWN?分別抬起每個手指,哪個 Button 的 Click 會被觸發?

小 B:當然是第一個收到 ACTION_DOWN,那麼應該也是第一個能觸發 click。

小 A:不錯不錯,你先去做個實驗,再決定要不要我去買可樂。

對話結束。

到這裡大家覺得小 B 回答的怎麼樣?

先別往下看,自己想想自己的回答應該是什麼,如果錯了,麻煩給我買瓶可樂。

小 B 回去測試。

大吼一聲:為了可樂!

快速寫完 Demo,分為自定義了一個 MyLinearLayout,MyButton,複寫dispatchTouchEvent,打上 Event 日誌,再加上 onclick 事件日誌。

按照之前的描述實驗:

一個 LinearLayout 內部有兩個 Button,當我第一個手指按在第一個 Button 上,第二個手指按在第二個 Button 上,這兩個 Button哪個會收到 ACTION_DOWN?分別抬起每個手指,哪個 Button 的 Click 會被觸發?

看到 Log,心涼了。

第一個手指按下第一個 Button 上,第一個 Button 收到 ACTION_DOWN。
第二個手指按在第二個 Button 上,第二個 Button 竟然也收到了 ACTION_DOWN。

分別抬起時,兩個 Button 的 Click 依次觸發。

注意:大家測試的時候,Button 可以搞大一些,兩個 Button 距離遠一些,防止誤觸。

小 B帶著兩瓶可樂來到小 A 面前,大哥趕緊給我講講。

小 A:

好,在非常早期,很多部落格的事件分發程式碼都是基於 2.x 系列的,那會程式碼是這樣的:

Android「打工人」:誰說事件分發很簡單的,我被這個給問哭了!

完整程式碼見這裡

MotionTarget 就是一個 View。而在後續的程式碼,"targetView"已經不再是一個獨立的 View 了,而是一個類似於連結串列。

// First touch target in the linked list of touch targets.private TouchTarget mFirstTouchTarget;private static final class TouchTarget {    // The touched child view.
    public View child;    // The next target in the target list.
    public TouchTarget next;
}

你順著這個差異去看原始碼就明白了。

小 B:這波不虧,雖然虧了兩瓶可樂,但是學到了。

好了,AB 角色結束,對話內容基本上是同事間日常對話,當然我故意潤色了一些。

再次友情提示: 在面試的時候,不要故意顯擺你知道一個事件分發邏輯可能有多個 ACTION_DOWN,一定要分情況說清楚,因為面試官很可能沒看過這篇文章,把你掛了別怪我...

最後

其實對於程式設計師來說,要學習的知識內容、技術有太多太多,要想不被環境淘汰就只有不斷提升自己, 從來都是我們去適應環境,而不是環境來適應我們!

這裡附上上述的技術體系圖相關的幾十套 騰訊、頭條、阿里、美團等公司19年的面試題,把技術點整理成了影片和PDF(實際上比預期多花了不少精力),包含 知識脈絡 + 諸多細節,由於篇幅有限,這裡以圖片的形式給大家展示一部分。

相信它會給大家帶來很多收穫:

Android「打工人」:誰說事件分發很簡單的,我被這個給問哭了!

資料太多,全部展示會影響篇幅,暫時就先列舉這些部分截圖,以上資源均免費分享,以上內容均放在了開源專案: github  中已收錄,大家可以自行獲取。

當程式設計師容易,當一個優秀的程式設計師是需要不斷學習的,從初級程式設計師到高階程式設計師,從初級架構師到資深架構師,或者走向管理,從技術經理到技術總監,每個階段都需要掌握不同的能力。早早確定自己的職業方向,才能在工作和能力提升中甩開同齡人。

最後如果你和小B錯的一樣,可樂我就不要了,點個贊可以吧~

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69983917/viewspace-2734566/,如需轉載,請註明出處,否則將追究法律責任。

相關文章