基于Android version 26 的源码对Android 事件传递进行分析
1 基础分析
1)Activity 处理事件的源码如下:
源码分析:Activity 收到系统事件就会调用 diapatchTouchEvent(ex)处理
在diapatchTouchEvent方法内部 调用 Activity 的 对应的 PhoneWindow的
superDiapatchTouchEvent(ex)来处理
2)phoneWindow 处理事件源码:
DecorView 的 处理源码和DecorView 的定义:
源码分析:
1)PhoneWindow 的superDispatchTouchEvent内部调用DecorView的 superDispatchTouchEvent
2)DecorView 的 super.dispatchTouchEvent(event); 内部调用 super.dispatchTouchEvent(event);
3) DecorView 是继承自 FrameLayout 实际调用的是 ViewGroup 的 dispatchTouchEvent(event);
3) ViewGroup 的 事件处理源码:
源码分析:
1) 接着就是查找当前的 focus child view 由外向里 传递事件,调用 child 的 dispatchTouchEvent
2)同时还有一个 intercepted 的 判断, 如果 onInterceptTouchEvent返回 true 则intercepted=true, 那么事件就不会再向viewgroup的 子view 传递
3) View group 里面如过 判断 onInterceptTouchEvent 返回true 以后的code 逻辑:如果当前没有 TouchTarget 则当前的ViewGroup 就是TouchTarget, 调用 dispatchTransformedTouchEvent 给当前的view
在 dispatchTransformedTouchEvent 方法里面 会调用:handled = super.dispatchTouchEvent(event);
让 ViewGroup的 super 也就是 View 类来处理 这个event
也就是 如果onInterceptTouchEvent返回 true 则 这个view group 就会当成一个 view 来handle event
4) View group 如何向子View 传递 并且check 子view的返回值:
a )会遍历所有的子view 并且判断 是否在 事件 touch 区域,然后调用 在dispatchTransformedTouchEvent 中 调用 handled = child.dispatchTouchEvent(event);
b) 在如果有child view dispatchTouchEvent 返回 true 则在 addTouchTarget(child, idBitsToAssign); 设置 mFirstTouchTarget的值 为当前child view。
如果 child view 返回 false,则mFirstTouchTarget 的值依然为 null 默认还是要调用 当前view group 的 dispatchTransformedTouchEvent 和 onTouchEvent
4) View 事件处理源码:
源码分析:
1)view 调用dispatchTouchEvent 会先判断 handleScrollBarDragging 和 li.mOnTouchListener.onTouch 如果这个两个返回true则表明 view 已经消费了事件,将不会调用 onTouchEvent()
2)如果以上两个不消费事件 才调用 onTouchEvent()
网友评论