android 快速理解view的事件分发

本文详细解析了Android中事件分发的过程,包括dispatchTouchEvent、onInterceptTouchEvent和onTouchEvent三个核心方法的功能及其相互关系,帮助读者理解事件如何在ViewGroup和View之间传递。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

事件的分发过程由三个主要的方法来共同完成:dispatchTouchEvent(MotionEvent ev),onInterceptTouchEvent(MotionEvent ev),onTouchEvent(MotionEvent ev),来看看他们分别有什么功能

public boolean dispatchTouchEvent(MotionEvent ev)
事件的分发就是通过这个方法来执行的,只要事件传递到了某个view,那个这个view的dispatchTouchEvent方法就一定会执行,返回值收当前view的onTouchEvent方法和子元素的dispatchTouchEvent影响,表示是否消耗当前事件。

public boolean onInterceptTouchEvent(MotionEvent ev)
在dispatchTouchEvent方法里面被调用,用来判断是否拦截事件,如果当前view拦截了某个事件,那么在同一个事件序列当中,这个方法不会被再次调用,返回值表示是否拦截事件。

public boolean onTouchEvent(MotionEvent ev)
在dispatchTouchEvent方法里面被调用,用来处理点击事件,返回值表示是否消耗当前事件,如果不消耗,那么在同一个事件序列当中,当前view无法再次接收到事件。

三个方法的关系可以用以下伪代码表示:
      public boolean dispatchTouchEvent(MotionEvent ev){
        boolean consume = false;
        if(onInterceptTouchEvent(ev)){
            consume = onTouchEvent(ev);
        }else {
            consume = child.dispatchTouchEvent(ev);
        }
        return consume;
    }

通过上面的伪代码,我们可以看出,对于一个viewgroup来说,一个事件产生,首先它的dispatchTouchEvent方法会调用,然后会执行它的onInterceptTouchEvent方法,如果onInterceptTouchEvent返回true,表示要拦截事件,则viewgroup的onTouchEvent方法会被调用,如果不拦截,viewgroup的子元素会接着调用dispatchTouchEvent方法。如果一个view需要消耗事件并且设置了onTouchListener,那么会执行onTouch方法,如果onTouch方法返回true,则不会调用onTouchEvent方法。返回false,则会调用。我们熟悉的onClick方法就是在onTouchEvent调用,也就是说如果设置了ontouchListener,就不会调用onClick方法。

总结一下
1:当一个事件产生,首先会传递给activity,activity再传递给window,最后由window传递给顶级view。然后按正常事件分发开始传递。如果子元素的onTouchEvent方法返回了false,也就是不处理事件,则会调用父容器的onTouchEvent。若果都不进行处理,最终会返回给activity,也就是activity的onTouchEvent方法被调用。就好比上级给下级分配任务,下级如果没有处理只能由上级再来处理。上级如果也没有处理,只能又更高级别的来处理。其中activity就相当于最高领导。

2:同一个事件序列是指手机触摸屏幕开始,直到离开屏幕结束。

3:一个事件序列只能被一个view拦截消耗,因为一旦一个元素拦截了此事件,那么同一事件序列内所有的事件都会交给它处理,,并且它的onInterceptTouchEvent方法不会再被调用,因为已经交由它处理,不需要在询问是否拦截了。因此同一事件序列的事件不会有两个view同时处理。除非在某个view的ontouch
event方法里把事件强行传递给别的view处理。

4:viewgroup默认不拦截任何事件。也就是onInterceptTouchEvent返回false。

5:view(排除viewgroup)因为不存在子元素,所以也没有onInterceptTouchEvent方法,一旦有事件传递给它,那么它的onTouchEvent方法就会被调用

6:view的onTouchEvent默认都会消耗事件,除非它是不可点击的

7:子元素可以通过requestDisallowInterceptTouchEvent方法干预父元素的事件分发,但是Down事件除外。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值