Android事件分發機制

Android事件分發機制

1、概述

本次分享有一個非常重要的概念:View,雖然說View不屬於四大組件,但是它的作用堪比四大組件,甚至比Receiver和Provider的重要性都要大。在Android開發中,Activity承擔這可視化的功能,同時Android系統提供了很多基礎控件,常見的有Button、TextView、CheckBox等。很多時候僅僅使用系統提供的控件是不能滿足需求的,因此我們就需要能夠根據需求進行新控件的定義,而控件的自定義就需要對Android的View體系有深入的理解,只有這樣才能寫出完美的自定義控件。同時Android手機屬於移動設備,移動設備的一個特點就是用戶可以直接通過屏幕來進行一系列操作,一個典型的場景就是屏幕的滑動,用戶可以通過滑動來切換到不同的界面。很多情況下我們的應用都需要支持滑動操作,當處於不同層級的View都可以響應用戶的滑動操作時,就會帶來一個問題,那就是滑動衝突。如何解決滑動衝突呢?這對於初學者來說的確是個頭疼的問題,其實解決滑動衝突本不難,它需要讀者對View的事件分發機制有一定的瞭解,在這個基礎上,我們就可以利於這個特性從而得出滑動衝突的解決方法。
——摘自Android開發藝術探索

2、事件分發概述

事件指的是什麼呢?就是指用戶觸摸屏幕產生的Touch事件;在Android中它被封裝成MotionEvent

3、常用MotionEvent分類

  • **ACTION_DOWN:**按下View(其他所有事件的開始)。
  • **ACTION_UP:**擡起View(與DOWN對應)。
  • **ACTION_MOVE:**滑動View。
  • **ACTION_CANCEL:**結束事件(非人爲原因)。

其餘事件:ACTION_MASKACTION_OUTSIDEACTION_POINTER_DOWN
ACTION_POINTER_UPACTION_HOVER_MOVEACTION_SCROLL
ACTION_HOVER_ENTERACTION_HOVER_EXITACTION_BUTTON_PRESS
ACTION_BUTTON_RELEASEACTION_POINTER_INDEX_MASK
ACTION_POINTER_INDEX_SHIFT;有興趣的可以下來自己瞭解。

3、事件產生順序在這裏插入圖片描述

4、Android事件扭轉流程

模擬:

經理分派任務,下屬處理這個任務的過程。

  • View層次示例
    在這裏插入圖片描述

  • View內部事件處理流程圖(借用郭大神一張圖):

在這裏插入圖片描述

5、事件分發流程及其分析

流程圖及註釋

在這裏插入圖片描述

流程分析

  • 流程1:在Activity#dispatchTouchEvent返回false/true
    當前流程是在Activity#dispatchTouchEvent攔截並消費事件,不再往下傳遞

03-26 18:54:58.178 com.android.api23 I/com.android.api23.MainActivity: dispatchTouchEvent#event:0

  • 流程2:在ViewGroup#dispatchTouchEvent返回true:
    當前流程是ViewGroup#dispatchTouchEvent攔截並消費事件,事件不再往下傳遞

03-26 19:08:23.268 com.android.api23 I/com.android.api23.MainActivity: dispatchTouchEvent#event:0
03-26 19:08:23.268 com.android.api23 I/com.android.api23.MyViewGroup: dispatchTouchEvent#event:0

  • 流程3:在ViewGroup#dispatchTouchEvent返回false:
    當前流程是停止往當前ViewGroup及其子View事件,並將當前事件交由父類onTouchEvent處理。

03-26 19:09:15.238 com.android.api23 I/com.android.api23.MainActivity: dispatchTouchEvent#event:0
03-26 19:09:15.238 com.android.api23 I/com.android.api23.MyViewGroup: dispatchTouchEvent#event:0
03-26 19:09:15.238 com.android.api23 I/com.android.api23.MainActivity: onTouchEvent#event:0

  • 流程4:在ViewGroup#onInterceptTouchEvent返回true:

03-26 19:07:02.918 com.android.api23 I/com.android.api23.MainActivity: dispatchTouchEvent#event:0
03-26 19:07:02.918 com.android.api23 I/com.android.api23.MyViewGroup: dispatchTouchEvent#event:0
03-26 19:07:02.918 com.android.api23 I/com.android.api23.MyViewGroup: onInterceptTouchEvent#event:0
03-26 19:07:02.918 com.android.api23 I/com.android.api23.MyViewGroup: onTouchEvent#event:0
03-26 19:07:02.918 com.android.api23 I/com.android.api23.MainActivity: onTouchEvent#event:0

  • 在ViewGroup#onInterceptTouchEvent返回false
    當前流程爲系統默認流程即:ViewGroup不攔截事件,事件將往下一級傳遞

03-26 19:06:11.008 com.android.api23 I/com.android.api23.MainActivity: dispatchTouchEvent#event:0
03-26 19:06:11.018 com.android.api23 I/com.android.api23.MyViewGroup: dispatchTouchEvent#event:0
03-26 19:06:11.018 com.android.api23 I/com.android.api23.MyViewGroup: onInterceptTouchEvent#event:0
03-26 19:06:11.018 com.android.api23 I/com.android.api23.MyView: dispatchTouchEvent#event:0
03-26 19:06:11.018 com.android.api23 I/com.android.api23.MyView: onTouchEvent#event:0
03-26 19:06:11.018 com.android.api23 I/com.android.api23.MyViewGroup: onTouchEvent#event:0
03-26 19:06:11.018 com.android.api23 I/com.android.api23.MainActivity: onTouchEvent#event:0

  • 流程5:在View#dispatchTouchEvent返回true:
    當前流程是ViewGroup#dispatchTouchEvent攔截並消費事件,事件不再往下傳遞

03-26 19:10:41.048 com.android.api23 I/com.android.api23.MainActivity: dispatchTouchEvent#event:0
03-26 19:10:41.048 com.android.api23 I/com.android.api23.MyViewGroup: dispatchTouchEvent#event:0
03-26 19:10:41.048 com.android.api23 I/com.android.api23.MyViewGroup: onInterceptTouchEvent#event:0
03-26 19:10:41.048 com.android.api23 I/com.android.api23.MyView: dispatchTouchEvent#event:0

  • 流程6:在View#dispatchTouchEvent返回false:

03-26 19:11:36.458 com.android.api23 I/com.android.api23.MainActivity: dispatchTouchEvent#event:0
03-26 19:11:36.458 com.android.api23 I/com.android.api23.MyViewGroup: dispatchTouchEvent#event:0
03-26 19:11:36.458 com.android.api23 I/com.android.api23.MyViewGroup: onInterceptTouchEvent#event:0
03-26 19:11:36.458 com.android.api23 I/com.android.api23.MyView: dispatchTouchEvent#event:0
03-26 19:11:36.458 com.android.api23 I/com.android.api23.MyViewGroup: onTouchEvent#event:0
03-26 19:11:36.458 com.android.api23 I/com.android.api23.MainActivity: onTouchEvent#event:0

  • 流程7:在View#onTouchEvent返回true:

03-26 19:12:51.688 com.android.api23 I/com.android.api23.MainActivity: dispatchTouchEvent#event:0
03-26 19:12:51.688 com.android.api23 I/com.android.api23.MyViewGroup: dispatchTouchEvent#event:0
03-26 19:12:51.688 com.android.api23 I/com.android.api23.MyViewGroup: onInterceptTouchEvent#event:0
03-26 19:12:51.688 com.android.api23 I/com.android.api23.MyView: dispatchTouchEvent#event:0
03-26 19:12:51.688 com.android.api23 I/com.android.api23.MyView: onTouchEvent#event:0

  • 在View#onTouchEvent返回false:
    當前流程爲系統默認流程

03-26 19:13:58.188 com.android.api23 I/com.android.api23.MainActivity: dispatchTouchEvent#event:0
03-26 19:13:58.188 com.android.api23 I/com.android.api23.MyViewGroup: dispatchTouchEvent#event:0
03-26 19:13:58.188 com.android.api23 I/com.android.api23.MyViewGroup: onInterceptTouchEvent#event:0
03-26 19:13:58.188 com.android.api23 I/com.android.api23.MyView: dispatchTouchEvent#event:0
03-26 19:13:58.188 com.android.api23 I/com.android.api23.MyView: onTouchEvent#event:0
03-26 19:13:58.188 com.android.api23 I/com.android.api23.MyViewGroup: onTouchEvent#event:0
03-26 19:13:58.188 com.android.api23 I/com.android.api23.MainActivity: onTouchEvent#event:0

  • 流程8:在ViewGroup#onTouchEvent返回true:

03-26 19:15:14.608 com.android.api23 I/com.android.api23.MainActivity: dispatchTouchEvent#event:0
03-26 19:15:14.608 com.android.api23 I/com.android.api23.MyViewGroup: dispatchTouchEvent#event:0
03-26 19:15:14.608 com.android.api23 I/com.android.api23.MyViewGroup: onInterceptTouchEvent#event:0
03-26 19:15:14.608 com.android.api23 I/com.android.api23.MyView: dispatchTouchEvent#event:0
03-26 19:15:14.608 com.android.api23 I/com.android.api23.MyView: onTouchEvent#event:0
03-26 19:15:14.608 com.android.api23 I/com.android.api23.MyViewGroup: onTouchEvent#event:0

  • 在ViewGroup#onTouchEvent返回false:
    當前流程爲系統默認流程

03-26 19:16:48.928 com.android.api23 I/com.android.api23.MainActivity: dispatchTouchEvent#event:0
03-26 19:16:48.928 com.android.api23 I/com.android.api23.MyViewGroup: dispatchTouchEvent#event:0
03-26 19:16:48.928 com.android.api23 I/com.android.api23.MyViewGroup: onInterceptTouchEvent#event:0
03-26 19:16:48.928 com.android.api23 I/com.android.api23.MyView: dispatchTouchEvent#event:0
03-26 19:16:48.928 com.android.api23 I/com.android.api23.MyView: onTouchEvent#event:0
03-26 19:16:48.928 com.android.api23 I/com.android.api23.MyViewGroup: onTouchEvent#event:0
03-26 19:16:48.928 com.android.api23 I/com.android.api23.MainActivity: onTouchEvent#event:0

  • 流程9:在Activity#onTouchEvent返回true:

03-26 19:18:49.648 com.android.api23 I/com.android.api23.MainActivity: dispatchTouchEvent#event:0
03-26 19:18:49.648 com.android.api23 I/com.android.api23.MyViewGroup: dispatchTouchEvent#event:0
03-26 19:18:49.648 com.android.api23 I/com.android.api23.MyViewGroup: onInterceptTouchEvent#event:0
03-26 19:18:49.648 com.android.api23 I/com.android.api23.MyView: dispatchTouchEvent#event:0
03-26 19:18:49.648 com.android.api23 I/com.android.api23.MyView: onTouchEvent#event:0
03-26 19:18:49.648 com.android.api23 I/com.android.api23.MyViewGroup: onTouchEvent#event:0
03-26 19:18:49.648 com.android.api23 I/com.android.api23.MainActivity: onTouchEvent#event:0

  • 在Activity#onTouchEvent返回false:
    當前流程爲系統默認流程

03-26 19:20:07.738 com.android.api23 I/com.android.api23.MainActivity: dispatchTouchEvent#event:0
03-26 19:20:07.738 com.android.api23 I/com.android.api23.MyViewGroup: dispatchTouchEvent#event:0
03-26 19:20:07.738 com.android.api23 I/com.android.api23.MyViewGroup: onInterceptTouchEvent#event:0
03-26 19:20:07.738 com.android.api23 I/com.android.api23.MyView: dispatchTouchEvent#event:0
03-26 19:20:07.738 com.android.api23 I/com.android.api23.MyView: onTouchEvent#event:0
03-26 19:20:07.738 com.android.api23 I/com.android.api23.MyViewGroup: onTouchEvent#event:0
03-26 19:20:07.738 com.android.api23 I/com.android.api23.MainActivity: onTouchEvent#event:0

AndroidApi23:Android事件分發機制測試Demo

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章