Android事件分發機制簡單理解
View只能處理事件,不能往下分發事件。ViewGroup要先分發事件,再處理事件。
ViewGroup中
事件分為 dispatchTouchEvent(事件的分發),onInterceptTouchEvent(事件的攔截,返回true 代表攔截事件),onTouchEvent(事件的處理,返回true代表消費事件)
View中
事件分為dispatchTouchEvent(事件的分發),onTouchEvent(事件的處理)。
事件分發的順序
Activity -> ViewGroup -> View。
從上層往下層分發(ViewGroup 即為上層,View 為下層),從下層往上層處理。
例子
class MyViewGroup(context: Context, attributeSet: AttributeSet): LinearLayout(context, attributeSet){
override fun dispatchTouchEvent(event: MotionEvent?): Boolean {
when (event?.action) {
MotionEvent.ACTION_DOWN -> {
Log.d("MyView.class", "ViewGroup_dispacth_DOWN")
}
MotionEvent.ACTION_MOVE -> {
Log.d("MyView.class", "ViewGroup_dispacth_MOVE")
}
MotionEvent.ACTION_UP -> {
Log.d("MyView.class", "ViewGroup_dispacth_UP")
}
}
return super.dispatchTouchEvent(event)
}
override fun onInterceptTouchEvent(ev: MotionEvent?): Boolean {
when (ev?.action) {
MotionEvent.ACTION_DOWN -> {
Log.d("MyView.class", "ViewGroup_intercept_DOWN")
}
MotionEvent.ACTION_MOVE -> {
Log.d("MyView.class", "ViewGroup_intercept_MOVE")
}
MotionEvent.ACTION_UP -> {
Log.d("MyView.class", "ViewGroup_intercept_UP")
}
}
return super.onInterceptTouchEvent(ev)
}
override fun onTouchEvent(event: MotionEvent?): Boolean {
when (event?.action) {
MotionEvent.ACTION_DOWN -> {
Log.d("MyView.class", "ViewGroup_onTouch_DOWN")
}
MotionEvent.ACTION_MOVE -> {
Log.d("MyView.class", "ViewGroup_onTouch_MOVE")
}
MotionEvent.ACTION_UP -> {
Log.d("MyView.class", "ViewGroup_onTouch_UP")
}
}
return super.onTouchEvent(event)
}
}
class MyView(context: Context, attributeSet: AttributeSet): View(context, attributeSet){
override fun dispatchTouchEvent(event: MotionEvent?): Boolean {
when (event?.action) {
MotionEvent.ACTION_DOWN -> {
Log.d("MyView.class", "View_dispacth_DOWN")
}
MotionEvent.ACTION_MOVE -> {
Log.d("MyView.class", "View_dispacth_MOVE")
}
MotionEvent.ACTION_UP -> {
Log.d("MyView.class", "View_dispacth_UP")
}
}
return super.dispatchTouchEvent(event)
}
override fun onTouchEvent(event: MotionEvent?): Boolean {
when (event?.action) {
MotionEvent.ACTION_DOWN -> {
Log.d("MyView.class", "View_onTouch_DOWN")
}
MotionEvent.ACTION_MOVE -> {
Log.d("MyView.class", "View_onTouch_MOVE")
}
MotionEvent.ACTION_UP -> {
Log.d("MyView.class", "View_onTouch_UP")
}
}
return super.onTouchEvent(event)
}
}
產生以下流程的事件均為點選custom_view
1. 對以上方法均不作處理,都返回super(呼叫父類方法,返回預設值)。這意味著我們既不攔截,也不消費。
2020-11-04 20:07:12.492 28679-28679/com.cl.eventtest D/MyView.class: Activity_dispatch_DOWN
2020-11-04 20:07:12.493 28679-28679/com.cl.eventtest D/MyView.class: ViewGroup_dispacth_DOWN
2020-11-04 20:07:12.493 28679-28679/com.cl.eventtest D/MyView.class: ViewGroup_intercept_DOWN
2020-11-04 20:07:12.493 28679-28679/com.cl.eventtest D/MyView.class: View_dispacth_DOWN
2020-11-04 20:07:12.495 28679-28679/com.cl.eventtest D/MyView.class: View_onTouch_DOWN
2020-11-04 20:07:12.496 28679-28679/com.cl.eventtest D/MyView.class: ViewGroup_onTouch_DOWN
2020-11-04 20:07:12.497 28679-28679/com.cl.eventtest D/MyView.class: Activity_onTouch_DOWN
2020-11-04 20:07:12.501 28679-28679/com.cl.eventtest D/MyView.class: Activity_dispatch_MOVE
2020-11-04 20:07:12.501 28679-28679/com.cl.eventtest D/MyView.class: Activity_onTouch_MOVE
2020-11-04 20:07:12.528 28679-28679/com.cl.eventtest D/MyView.class: Activity_dispatch_MOVE
2020-11-04 20:07:12.528 28679-28679/com.cl.eventtest D/MyView.class: Activity_onTouch_MOVE
2020-11-04 20:07:12.529 28679-28679/com.cl.eventtest D/MyView.class: Activity_dispatch_UP
2020-11-04 20:07:12.529 28679-28679/com.cl.eventtest D/MyView.class: Activity_onTouch_UP
如果對事件既不攔截,也不消費,當觸發ACTION_DOWN的時候,事件會經過Activity——ViewGroup——View一層層的向下進行dispatchTouchEvent(分發)—onInterceptTouchEvent(攔截)呼叫。當到達最底層View後,開始觸發消費操作,因為均不消費,ACTION_DOWN將由底層一層層向上冒,移交上層處理。當抵達最上層Activity後,說明下層均不消費,之後觸發的ACTION_MOVE和ACTION_UP將不再向下層分發傳遞,直接交由Activity分發給自己進行處理。
2.將VIewGroup的onInterceptTouchEvent返回值改為true,即意味著ViewGroup攔截事件,但是並沒有消費。
2020-11-04 20:14:33.591 3187-3187/com.cl.eventtest D/MyView.class: Activity_dispatch_DOWN
2020-11-04 20:14:33.592 3187-3187/com.cl.eventtest D/MyView.class: ViewGroup_dispacth_DOWN
2020-11-04 20:14:33.592 3187-3187/com.cl.eventtest D/MyView.class: ViewGroup_intercept_DOWN
2020-11-04 20:14:33.592 3187-3187/com.cl.eventtest D/MyView.class: ViewGroup_onTouch_DOWN
2020-11-04 20:14:33.593 3187-3187/com.cl.eventtest D/MyView.class: Activity_onTouch_DOWN
2020-11-04 20:14:33.622 3187-3187/com.cl.eventtest D/MyView.class: Activity_dispatch_MOVE
2020-11-04 20:14:33.622 3187-3187/com.cl.eventtest D/MyView.class: Activity_onTouch_MOVE
2020-11-04 20:14:33.630 3187-3187/com.cl.eventtest D/MyView.class: Activity_dispatch_UP
2020-11-04 20:14:33.630 3187-3187/com.cl.eventtest D/MyView.class: Activity_onTouch_UP
只是攔截事件,但是沒有消費事件,那麼 dispatchTouchEvent 不會繼續往下呼叫,但是 onTouchEvent()還是會一層層往上呼叫。
3. ViewGroup的 onInterceptTouchEvent() 仍然返回super.onInterceptTouchEvent(),但是 onTouchEvent() 返回 true。即表示ViewGroup不攔截事件,但是消費事件。
2020-11-04 20:22:49.363 4290-4290/com.cl.eventtest D/MyView.class: Activity_dispatch_DOWN
2020-11-04 20:22:49.364 4290-4290/com.cl.eventtest D/MyView.class: ViewGroup_dispacth_DOWN
2020-11-04 20:22:49.364 4290-4290/com.cl.eventtest D/MyView.class: ViewGroup_intercept_DOWN
2020-11-04 20:22:49.364 4290-4290/com.cl.eventtest D/MyView.class: View_dispacth_DOWN
2020-11-04 20:22:49.365 4290-4290/com.cl.eventtest D/MyView.class: View_onTouch_DOWN
2020-11-04 20:22:49.366 4290-4290/com.cl.eventtest D/MyView.class: ViewGroup_onTouch_DOWN
2020-11-04 20:22:49.367 4290-4290/com.cl.eventtest D/MyView.class: Activity_dispatch_MOVE
2020-11-04 20:22:49.367 4290-4290/com.cl.eventtest D/MyView.class: ViewGroup_dispacth_MOVE
2020-11-04 20:22:49.367 4290-4290/com.cl.eventtest D/MyView.class: ViewGroup_onTouch_MOVE
2020-11-04 20:22:49.368 4290-4290/com.cl.eventtest D/MyView.class: Activity_dispatch_UP
2020-11-04 20:22:49.368 4290-4290/com.cl.eventtest D/MyView.class: ViewGroup_dispacth_UP
2020-11-04 20:22:49.368 4290-4290/com.cl.eventtest D/MyView.class: ViewGroup_onTouch_UP
此時因為沒有攔截事件,Down事件仍然會下發到View ,但是事件在 ViewGroup 中消費了,所以不會向上傳遞給 Activity 處理。
同時之後的 MOVE 以及 UP 事件都不會向下分發到 View ,因為已經知道DOWN事件被ViewGroup消費了。
4. ViewGroup的 onInterceptTouchEvent() 和onTouchEvent() 的返回值均改為true,則意味著ViewGroup既攔截了事件,同時也消費了事件。
2020-11-04 20:31:00.920 6527-6527/com.cl.eventtest D/MyView.class: Activity_dispatch_DOWN
2020-11-04 20:31:00.925 6527-6527/com.cl.eventtest D/MyView.class: ViewGroup_dispacth_DOWN
2020-11-04 20:31:00.925 6527-6527/com.cl.eventtest D/MyView.class: ViewGroup_intercept_DOWN
2020-11-04 20:31:00.926 6527-6527/com.cl.eventtest D/MyView.class: ViewGroup_onTouch_DOWN
2020-11-04 20:31:00.938 6527-6527/com.cl.eventtest D/MyView.class: Activity_dispatch_MOVE
2020-11-04 20:31:00.938 6527-6527/com.cl.eventtest D/MyView.class: ViewGroup_dispacth_MOVE
2020-11-04 20:31:00.938 6527-6527/com.cl.eventtest D/MyView.class: ViewGroup_onTouch_MOVE
2020-11-04 20:31:00.959 6527-6527/com.cl.eventtest D/MyView.class: Activity_dispatch_MOVE
2020-11-04 20:31:00.959 6527-6527/com.cl.eventtest D/MyView.class: ViewGroup_dispacth_MOVE
2020-11-04 20:31:00.959 6527-6527/com.cl.eventtest D/MyView.class: ViewGroup_onTouch_MOVE
2020-11-04 20:31:00.959 6527-6527/com.cl.eventtest D/MyView.class: Activity_dispatch_UP
2020-11-04 20:31:00.959 6527-6527/com.cl.eventtest D/MyView.class: ViewGroup_dispacth_UP
2020-11-04 20:31:00.959 6527-6527/com.cl.eventtest D/MyView.class: ViewGroup_onTouch_UP
此時事件不會再向下至 View 分發,同時 也不會向上傳遞到 Activity 處理。
相關文章
- Android 事件分發機制的理解Android事件
- Android事件分發機制Android事件
- android事件分發機制詳解Android事件
- Android的MotionEvent事件分發機制Android事件
- Android事件分發機制三:事件分發工作流程Android事件
- Android View 的事件體系 -- 事件分發機制AndroidView事件
- 淺談Android 事件分發機制(二)Android事件
- Android事件分發:從原始碼角度分析View事件分發機制Android事件原始碼View
- 淺談Android中的事件分發機制Android事件
- 【Android基礎】講講Android的事件分發機制Android事件
- Android事件分發機制,你瞭解過嗎?Android事件
- Android 事件分發機制原始碼解析-view層Android事件原始碼View
- 面試:講講 Android 的事件分發機制面試Android事件
- Android從原始碼角度剖析View事件分發機制Android原始碼View事件
- Android 事件分發機制原始碼詳解-最新 APIAndroid事件原始碼API
- 基於原始碼分析 Android View 事件分發機制原始碼AndroidView事件
- Android自定義View之事件分發機制總結AndroidView事件
- View事件分發機制分析View事件
- cocos EventDispatcher事件分發機制事件
- Android事件分發機制:基礎篇:最全面、最易懂Android事件
- Android事件分發機制五:面試官你坐啊Android事件面試
- android觸控事件分發機制,曾困惑你我的地方Android事件
- 事件分發機制(一):解惑篇事件
- 【朝花夕拾】Android自定義View篇之(五)Android事件分發及傳遞機制AndroidView事件
- android 事件分發Android事件
- 事件分發機制(二):原始碼篇事件原始碼
- 一道簡單面試題理解JS事件機制(+1白話講解)面試題JS事件
- 深入理解DOM事件機制事件
- vscode原始碼分析【五】事件分發機制VSCode原始碼事件
- 2018.03.08、View的事件分發機制筆記View事件筆記
- 理解 Android 訊息機制Android
- 拇指記者深入Android公司,打探事件分發機制背後的祕密Android事件
- 深入淺出Android事件分發機制:最全面最易懂:基礎篇(一)Android事件
- 那些你曾不知道的觸控事件—Android分發機制完全解析事件Android
- Android事件分發機制本質是樹的深度遍歷(圖+原始碼)Android事件原始碼
- 深入理解React:事件機制原理React事件
- 深入理解非同步事件機制非同步事件
- 觸控事件分發核心機制優化吸收事件優化