zoukankan      html  css  js  c++  java
  • Android事件分发机制

          今天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)

  • 相关阅读:
    退休夫妇不顾反对坚持创业,把自己的品牌推向了市场
    年终将至,财务人如何做好数据分析?
    圣诞快乐:Oracle Database 19c 的10大新特性一览
    perl 获取表记录数
    rex 防止调度还没完成后又继续发起
    希腊女孩创办自媒体教希腊语,如今用户已达1000人
    在20天里赚三千多元,他靠创意经营商店,扩大了店面
    小杂货店的崛起,他坚信创新和拼搏是成功的两大法宝
    thinkphp
    thinkphp
  • 原文地址:https://www.cnblogs.com/zhouliweiblog/p/5496520.html
Copyright © 2011-2022 走看看