码迷,mamicode.com
首页 > 移动开发 > 详细

Android事件分发机制

时间:2019-09-06 01:25:46      阅读:120      评论:0      收藏:0      [点我收藏+]

标签:group   test   inter   dism   控件   demo   wro   input   设计   

      今天coding,无意写了个小bug出来,dialog去dismiss的时候不起作用,后来排查到是在dispatchTouchEvent中去show dialog时,有可能会创建两个Dialog,然后监听回调还是第一个的,当dismiss的时候,mDocorView是null的,所以dismiss的时候,就直接return掉,没有执行dismiss的逻辑。总结来说这个bug还是因为自己对事件分发理解的不透彻,正好之前没总结过,所以就写一遍博客记录下,方便自己之后查看。

  首先我们直接把View和ViewGroup一起来看,写一个demo,demo很简单,自定义两个View:一个继承Button(TestEventBtn),一个继承LinearLayout(TestEventDispatchLayout),然后这个Button放到TestEventDispatchLayout上,网上大部分的例子应该都是这个做demo的吧。之后就分别实现他们的dispatchTouch、onTouchEvent、onInterceptTouchEvent(只有ViewGroup有)、另外在Activity中把两个控件的onClickListener也加上。

  1)首先我们来做做实验,通过实验肯定有些情况不明白的,再看代码。

  •  点击TestEventDispatchLayout除了TestEventBtn之外的区域:

技术图片

从上面的日志我们可以看出touch事件首先是在被点击到的区域传递。从Activity到TestEventDispatchLayout传递了ACTION_UP和ACTION_DOWN事件,最后被TestEventDispatchLayout的onClick把事件吃掉,我们改动下,不设置onClickListener看看会怎么样:

  • 点击TestEvent:

技术图片

  • 点击TestEventDispatchLayout之外的区域:

技术图片

上面三种情况都是从MainActivity 的dispatchTouchEvent开始的,我们可以debug抓个trace看下点击事件传递路径:

技术图片

从这个堆栈,我们大致可以看出,最下面应该是硬件层会不停的检测是否有touch事件,当有touch事件时,会通过InputEventReceiver去dispatchInputEvent,接着中间这一大块都是在ViewRootImpl中的处理。

基本都是对事件的处理和传递,最后会传递到PhoneWindow的DecorView中dispatchTouchEvent,它的源码是:

技术图片

熟悉代码的同学可能会对这个Callback特别熟悉,Activity就实现了这个callback,因此这里的Callback就是Activity,好了,这就验证了上面的都是从Activity的dispaTouchEvent开始了。

从网上找了一个哥们的图,如下,能比较直观的理解事件传递过程。

技术图片

一个View就像一棵树一样,touch事件从根依次的传递到叶子的view。这也是android设计巧妙的地方,用了组合设计模式。

2)

 

Android事件分发机制

标签:group   test   inter   dism   控件   demo   wro   input   设计   

原文地址:https://www.cnblogs.com/zhouliweiblog/p/5496520.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!