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

Android事件分发机制原理

作者: 海晨忆 | 来源:发表于2018-02-12 13:43 被阅读78次

推荐:非著名程序员安卓自定义View教程目录,我的自定义view就是看他的这个系列学会的

  首先,我们需要确认的是android的事件传递机制是责任链模式,如果自己能处理就拦截下来自己处理,如果自己处理不了或者不确定就传递给下一个对象

事件的拦截、分发、消费

  我们要知道三个方法,控制事件反而拦截,分发与消费。如下表:

类型 相关方法 Activity ViewGroup View
事件分发 dispatchTouchEvent
事件拦截 onInterceptTouchEvent
事件处理 onTouchEvent

以上三个方法,均有boolean类型的返回值,通过设置true,false来控制事件传递的流程

Activity和View均没有事件拦截方法,是因为

  • Activity作为事件响应起点,如果,Activity把事件拦截了,辣么将为导致整个屏幕都无法点击

  • View作为事件响应的最末端,要么消费事件,要么不处理回传,没必要拦截事件

事件分发流程

  先给出一张图 分发流程

  这里,我们看到多了两个东西,一个是PhoneWindow,一个是DecorView,我们平时写的布局,最外层的父布局就是这里的RootView,有过几个app开发经验的程序员都应该知道,app的状态栏颜色的修改,还有那个主题的内容修改,修改后显示在哪呢?没错,就是DecorView里面。

  再有就是phoneWindow,其实,知不知道没什么用,phonewindow是Window的唯一实现类,Window是干嘛的呢?Window是一个抽象类,所有的视图,事件传递都归它管理,所以,phonewindow管理视图,上面说的DecorView就是phonewindow的一个内部实现类,除了自己的功能外,还负责消息传递。

  说了这么多,该来讲讲事件传递的流程了。android的view是树形结构的,基于这样的结构,我们的事件可以有序的分发。事件收集之后,起点是Activity,然后有序的向下传递,大致如下:

Activity -> PhoneWindow -> DecorView -> ViewGroup -> ... -> View

如果这个事件没有对象处理,辣么,它会依次往回传递,如果还是没有人处理,辣么就会被Activity抛弃掉

Activity <- PhoneWindow <- DecorView <- ViewGroup <- ... <- View

这就是文章开头我们提到的,责任链模式

下面我给出ViewGroup的事件分发机制的伪代码:

public boolean dispatchTouchEvent(MotionEvent ev) {
    boolean result = false;             // 默认状态为没有消费过

    if (!onInterceptTouchEvent(ev)) {   // 如果没有拦截交给子View
        result = child.dispatchTouchEvent(ev);
    }

    if (!result) {                      // 如果事件没有被消费,询问自身onTouchEvent
        result = onTouchEvent(ev);
    }

    return result;
}
  • 情景:老板: 我看公司最近业务不咋地,准备发展一下电商业务,下周之前做个淘宝出来试试怎么样。
    事件顺序,老板(MainActivity)要做淘宝,这个事件通过各个部门(ViewGroup)一层一层的往下传,传到最底层的时候,码农小王(View1)发现做不了,于是消息又一层一层的回传到老板那里。
    可以看到整个事件传递路线非常有序。从Activity开始,最后回传给Activity结束(由于我们无法操作Phone Window和DecorView,所以没有它们的信息)。
MainActivity [老板]: dispatchTouchEvent     经理,我准备发展一下电商业务,下周之前做一个淘宝出来.
RootView     [经理]: dispatchTouchEvent     呼叫技术部,老板要做淘宝,下周上线.
RootView     [经理]: onInterceptTouchEvent  (老板可能疯了,但又不是我做.)
ViewGroupA   [组长]: dispatchTouchEvent     老板要做淘宝,下周上线?
ViewGroupA   [组长]: onInterceptTouchEvent  (看着不太靠谱,先问问小王怎么看)
View1        [码农]: dispatchTouchEvent     做淘宝???
View1        [码农]: onTouchEvent           这个真心做不了啊.
ViewGroupA   [组长]: onTouchEvent           小王说做不了.
RootView     [经理]: onTouchEvent           报告老板, 技术部说做不了.
MainActivity [老板]: onTouchEvent           这么简单都做不了,你们都是干啥的(愤怒).

总结

事件分发机制设计到到情形非常多,这里就不一一列举了,记住以下几条原则就行了。

  1. 如果事件被消费,就意味着事件信息传递终止。

  2. 如果事件一直没有被消费,最后会传给Activity,如果Activity也不需要就被抛弃。

  3. 判断事件是否被消费是根据返回值,而不是根据你是否使用了事件。

end

相关文章

网友评论

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

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