一张图搞定安卓事件传递机制

先来看一个例子

在一个界面上有一个按钮1,现在在按钮1上覆盖一个按钮2,然后点击按钮2,请问底下的按钮1能拿到点击事件吗?

要搞懂这个问题,首先我们必须对安卓的事件分发机制有一个基本的了解,接下来我用3W1H的方式说明:

一张图搞定安卓事件传递机制_第1张图片
事件传递机制
  • 分发:表示事件未找到消费地点,将交给自身的下一函数处理;拦截:表示事件不再传递给子类;消费:表示事件找到消费地点,事件传递完结
  • 从图上我们可以知道,安卓的事件分发机制其实就容器和控件通过分发和拦截,沿着视图树向下传递触摸事件,当到达底层控件或者被拦截时,表示事件不在线下分发,继而沿着视图树向上寻找真正消费的地方的过程。

在回来看看之前的例子,它的视图树应该是这样的:


一张图搞定安卓事件传递机制_第2张图片
视图树

分析

  • 从图中我们可以看到Button2和Button1是并列关系,而且Button2优先于Button1
  • 问题问的是button1是否会拿到触摸事件,Button本身已经是最小的单位了,这里分析就是View中事件传递的问题
  • 事件传递中View拥有dispatchTouchEvent和onTouchEvent两个方法,即分发和消费。
  • 这里的Button是原生的控件并未人为干扰,View控件的事件触发顺序是先执行onTouch方法,在最后执行onClick方法,如果onTouch返回true,则不会调用onClick方法。 onTouch和onTouchEvent以及onClick的顺序,有什么区别,又该如何使用?

当用户点击Button2时候,事件会这么传递:

一张图搞定安卓事件传递机制_第3张图片
Button2事件传递

因此我们可以知道,如果点击了Buttn2,点击事件会在Button2的onClick事件中消费掉,Button1是拿不到点击事件的,也拿不到任何触摸事件,除非在Button2中重写了分发方法,不走super方法,直接返回true,那么Button1中将拿到触摸事件。

一张图搞定安卓事件传递机制_第4张图片
Button1拿到事件

-END-

你可能感兴趣的:(一张图搞定安卓事件传递机制)