浅谈android 点击事件分发处理流程

在Android的事件处理过程中,经常会遇到需要拦截事件或者手动分发事件的情况,所以简单的了解一下Android的事件分发处理机制还是很有必要的。接下来, 借助一个简单的UI布局说明一下android的事件分发处理的工作流程!!
UI的简单的布局如图:
这里写图片描述

其中HELLO这个button为我们自定义的Button1,蓝色背景的布局为我们自定义的Group2,红色的为Group1。布局的xml如下所示:

<?xml version="1.0" encoding="utf-8"?>
<camera2.android.com.clickevent.Group1 xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@color/colorAccent">

    <camera2.android.com.clickevent.Group2
        android:layout_width="200dp"
        android:layout_height="200dp"
        android:background="@color/colorPrimaryDark">

        <camera2.android.com.clickevent.Button1
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="hello" />
    </camera2.android.com.clickevent.Group2>

</camera2.android.com.clickevent.Group1>

现在开始测试:
首先点击最外层的布局——Group1,打印的Log如下所示:

08-27 06:37:41.143 5428-5428/camera2.android.com.clickevent I/zyq: Group1-------onInterceptTouchEvent=false
08-27 06:37:41.143 5428-5428/camera2.android.com.clickevent I/zyq: Group1-------onTouchEvent=false
08-27 06:37:41.143 5428-5428/camera2.android.com.clickevent I/zyq: Group1-------dispatchTouchEvent=false

从log中可以看出,当我们点击一个view的时候,点击事件的分发和处理涉及到这三个方法:onInterceptTouchEvent、onTouchEvent、dispatchTouchEvent。
如果没有特殊的情况,这三个方法一般都是会走到的,而且在一个view中,当点击事件发生后,方法的执行顺序为:
onInterceptTouchEvent —>onTouchEvent—>dispatchTouchEvent

现在点击group2,打印的log如下:

08-27 06:37:56.085 5428-5428/camera2.android.com.clickevent I/zyq: Group1-------onInterceptTouchEvent=false
08-27 06:37:56.085 5428-5428/camera2.android.com.clickevent I/zyq: Group2-------onInterceptTouchEvent=false
08-27 06:37:56.085 5428-5428/camera2.android.com.clickevent I/zyq: Group2-------onTouchEvent=false
08-27 06:37:56.085 5428-5428/camera2.android.com.clickevent I/zyq: Group2-------dispatchTouchEvent=false
08-27 06:37:56.085 5428-5428/camera2.android.com.clickevent I/zyq: Group1-------onTouchEvent=false
08-27 06:37:56.085 5428-5428/camera2.android.com.clickevent I/zyq: Group1-------dispatchTouchEvent=false

根据log可以看出,首先捕捉到点击事件发生的View是最外层的UI,所以Group1有权决定是否将此次的点击事件中断,如果中断,将直接有Group1的onTouchEvent方法处理此次的点击事件,通过dispatchTouchEvent方发返回此次事件是否被消耗或者是否被分发成功等。

方法的执行流程为:
group1.onInterceptTouch—>group2.onInterceptTouch—>group2.onTouchEvent—>group2.dispatchTouchEvent—>group1.onTouchEvent—>group1.dispatchTouchEvent.

这是在事件没有任何处理的情况下会执行的流程,一旦事件被处理或者在onTouchEvent或者dispatchTouchEvent方法中返回true,那么都会表示这个事件已经被消耗,其外层的View将不会执行onTouchEvent方法,而是直接通过dispatchTouchEvent方法返回true,告诉其他相对外层的View事件已经被消耗!!

点击Button1,打印log如下:

ACTION_DOWN

08-27 06:38:51.301 5579-5579/camera2.android.com.clickevent I/zyq: Group1-------onInterceptTouchEvent=false
08-27 06:38:51.301 5579-5579/camera2.android.com.clickevent I/zyq: Group2-------onInterceptTouchEvent=false
08-27 06:38:51.303 5579-5579/camera2.android.com.clickevent I/zyq: Button1------onTouchEvent = true
08-27 06:38:51.303 5579-5579/camera2.android.com.clickevent I/zyq: Button1------dispatchTouchEvent = true
08-27 06:38:51.303 5579-5579/camera2.android.com.clickevent I/zyq: Group2-------dispatchTouchEvent=true
08-27 06:38:51.304 5579-5579/camera2.android.com.clickevent I/zyq: Group1-------dispatchTouchEvent=true

ACTION_UP
08-27 06:38:51.432 5579-5579/camera2.android.com.clickevent I/zyq: Group1-------onInterceptTouchEvent=false
08-27 06:38:51.432 5579-5579/camera2.android.com.clickevent I/zyq: Group2-------onInterceptTouchEvent=false
08-27 06:38:51.433 5579-5579/camera2.android.com.clickevent I/zyq: Button1------onTouchEvent = true
08-27 06:38:51.433 5579-5579/camera2.android.com.clickevent I/zyq: Button1------dispatchTouchEvent = true
08-27 06:38:51.433 5579-5579/camera2.android.com.clickevent I/zyq: Group2-------dispatchTouchEvent=true
08-27 06:38:51.433 5579-5579/camera2.android.com.clickevent I/zyq: Group1-------dispatchTouchEvent=true

点击了一下按钮,会执行两遍,这个就不多说了,看一下流程,基本与前面类似,但是由于Button1是继承至Button,可以有效的消耗用户的点击事件,所以group2和group1的onTouchEvent方法都没有执行,只是通过dispatchTouchEvent向相对外层的View说明事件的是否被消耗。

如果我们想要使得所有button点击事件都有Group2处理,不论group2能否正确处理都不能够将事件重新返回给Group1处理的话,我们可以选择使用事件拦截,首先在group2的onInterceptEvent方法中返回true,使得Group2拦截group2容器中的view点击事件,可以在group2的onTouchEvent或者dispatchTouchEvent方法中返回true,使其通知group1,这个事件已经被消耗,不需要group1在进行处理。

在没有事件拦截的情况下,最先执行的onTouchEvent方法的View肯定是用户点击的那个view。

关于Android的事件分发处理流程就说到这里,有兴趣的可以关注我一下,有什么问题可以相互讨论一下,谢谢!!

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值