美文网首页
Android事件分发机制

Android事件分发机制

作者: nmssdmf | 来源:发表于2018-11-06 13:45 被阅读0次
    事件分发机制.PNG

    如上图所示,这是事件ACTION_DOWN的流程图,而ACTION_MOVEACTION_UP则是根据ACTION_DOWN的消费来定。

    • 如果ViewGroupAView都没有对ACTION_DOWN事件进行消费,则ACTION_MOVE的流程就是Activity.dispatch->Activity.onTouch
    • 如果ViewonTouch返回了true,对ACTION_DOWN进行了消费,则ACTION_MOVE的流程是Activity.dispath->ViewGroupA.dispatch->ViewGroupA.onIntercept->View.dispatch->View.onTouch

    下面分析一下源码:

    activity_dispatchTouchEvent.png
    1. MainActivity继承Activity且重写dispatchTouchEvent,不调用super.dispatchTouchEvent,则事件不再继续.

    2. 当点击事件触发,先调用Activity中的dispatchTouchEvent方法,然后调用的getWindow().superDispatchTouchEvent(ev),再看if条件,如果getWindow().superDispatchTouchEvent(ev)返回true,则直接return,如果返回false才走onTouchEvent.

    3. 看看getWindow().superDispatchTouchEvent(ev),这边直接调用了WindowsuperDispatchTouchEvent,Window是一个虚类,所以该方法在子类中实现,根据Window类上面的注释The only existing implementation of this abstract class is android.view.PhoneWindow,找到PhoneWindow.

    PhoneWindow_superDispatchTouchEvent.png

    ,再看mDecor,

    PhoneWindow_mDecor.png

    注释也得很清楚了,top-level view of the window.并且从代码中可以知道,DecorView继承了FragmeLayout,FrameLayout继承自ViewGroup.

    DectorView_superDispatchTouchEvent.png

    所以调用了ViewGroupdispatchTouchEvent方法.

    1. 那来看看ViewGroupdispatchTouchEvent方法,一看源码,好长一段,一步步看吧.
    viewgroup_dispatchTouchEvent_1.png

    这个标着红色的,不在ViewGroup里面,因为ViewGroup继承View,就去View中了下

    View_mInputEventConsistencyVerifier.png

    看不懂只能看注释了,注释还是写的很清楚的,用于调试的一致性验证器,这是用于调试的,跟我们没多大关系,然后接着往下看,

    viewgroup_dispatchTouchEvent_2.png

    解释一下这堆代码,第一个条件ev.isTargetAccessibilityFocus():是否应该被有焦点的控件先处理,第二个条件isAccessibilityFocusedViewOrHost():没有焦点, 不处理这个事件,结果ev.setTargetAccessibilityFocus(false);:目标View已经处理过了来, 接着用正常逻辑分发,这部分解释是网络上抄来的.继续看源码if (onFilterTouchEventForSecurity(ev))这个方法有注释,是用来过滤事件以应用安全策略.

    viewgroup_dispatchTouchEvent_3.png

    直接看一下cancelAndClearTouchTargets方法,点击看注释Cancels and clears all touch targets.:取消和清除所有触摸目标,再看resetTouchState方法,继续看注释Resets all touch state in preparation for a new cycle.:重置所有的触摸状态以准备一个新的周期,我的理解,Action_Down作为新一轮事件的开始,就摒弃之前触摸事件的状态,重新进入周期.

    viewgroup_dispatchTouchEvent_4.png

    关于resetTouchState还得讲一下,方法里面有一个mGroupFlags &= ~FLAG_DISALLOW_INTERCEPT;后面需要用到.接着往下看

    viewgroup_dispatchTouchEvent_5.png

    先看if里面的条件,条件一actionMasked == MotionEvent.ACTION_DOWN当为Action_down事件的时候,if成立,此时第二个条件mFirstTouchTarget != null是不成立的,代码在resetTouchState方法里的clearTouchTargets,就不多解释了,反过来,第一个条件不成立时,就不会重新清楚状态,上面讲了,只有action_down时,才会清除状态,所以第一个条件不成立时,第二个条件是成立的.那就是不管咋样,if都是成立的,那要else干啥,只能看注释了:没有触摸目标,这个动作不是最初的,因此这个视图组继续拦截触摸.这就可以理解了.接着看下一个条件final boolean disallowIntercept = (mGroupFlags & FLAG_DISALLOW_INTERCEPT) != 0;上面在clearTouchTargets中提到mGroupFlags &= ~FLAG_DISALLOW_INTERCEPT;,这两个一看就是0.所以disallowIntercept = flase,下面的if条件成立,进而会调用onInterceptTouchEvent(ev);拦截方法.

    接着往下看:

    viewgroup_dispatchTouchEvent_6.PNG

    在红线标注的这两个地方调用了dispatchTransformedTouchEvent

    viewgroup_dispatchTouchEvent_7.PNG

    从源码中看出,当该ViewGroupchildView的时候,就调用super.dispatchTouchEvent,如果还是ViewGroup,则继续调用child.dispatchTouchEvent

    相关文章

      网友评论

          本文标题:Android事件分发机制

          本文链接:https://www.haomeiwen.com/subject/kbwcsxtx.html