Android事件分发机制(小白学习篇)

最近在深入学习事件分发机制,一直被虐终于学有所成,特意把学后的总结记录下来,方便日后复习,也希望能帮助更多在事件分发上迷惑的人们。

首先你需要知道事件分发的对象有:Activity,Window,ViewGroup和View
其次你需要知道什么是事件流:ACTION_DOWN开始,数量不定的ACTION_MOVE和ACTION_UP组成了一个完整的事件流

如果以上两点你不知道,你可以先去学习下再来看这篇文章

這篇博客不按照市面上的那些套路来讲事件分发,直接上代码吓坏了读者,也不容易让读者理解,我们都从身边的事举例子延伸到代码中

  return (e = b = c = d = a = 3) == 3 ? true : false;

这条赋值语句很好懂,结果是返回true,能懂这一步你就知道了事件分发的核心思想(下面看下事件分发思想的伪代码)

  return (consume=Activity.disPatchTouchEvent(ev)= Window.disPatchTouchEvent(ev)
        = ViewGroup.disPatchTouchEvent(ev)= View.disPatchTouchEvent(ev))?true:false;

事件从Activity下发,一直到View结束,不断赋值,如果返回true此事件被消费了,返回false表示事件没有任何View消费

根据上面的伪代码我们可以得到如下结论:

1 每个事件分发的对象都有一个disPatchTouchEvent方法

2 如果其中一个disPatchTouchEvent返回true或者false,后面的disPatchTouchEvent就无效了(java代码里,常量不能被赋值也能和伪代码对应起来)

3 只有当disPatchTouchEvent未知的时候(super.dispatch)才可以继续往下传递形成一个完整的传递链

记住这个概念是很枯燥,那我们举个例子:

自定义ViewGroup  A里面有个Button B,重写A的disPatchTouchEvent方法直接返回true,重写B的disPatchTouchEvent方法输出“B是一个快乐的Button”,当我们点击B的时候会输出什么呢?

没错,什么也不会输出,如果你很容易懂了这一点我们就继续,如果没懂,请再把上面的结论思考一遍~

当我们在网上各种百度事件分发的时候总会告诉我们有三个方法:
disPatchTouchEvent,onInterceptTouchEvent,onTouchEvent
这三个方法都是做什么的呢?和事件分发有什么关系呢?下面我用最精炼的语言总结下:

disPatchTouchEvent:消费事件(true)/不消费事件(false)/分发事件(super)

onInterceptTouchEvent: 拦截事件(true)/不拦截事件(false 默认值)

onTouchEvent : 消费(true)/不消费(false)/ 根据View属性判断是否消费(super)

接下来看任玉刚大神ViewGroup的伪代码:

pulic boolean disPatchTouchEvent(MotionEvent ev){
   boolean consume=false;
   if(onInterceptTouchEvent(ev)){
     consume=onTouchEvent(ev);
   }else{
   consum=child.disPatchTouchEvent(ev)
   }
   return consume;
}

这段代码可以算是很精髓了,把ViewGroup到View的传递的本质描述的淋漓尽致

关于事件分发的补充:

1 只有ViewGroup有onInterceptTouchEvent方法,其他的没有

所以View的disPatchTouchEvent伪代码

pulic boolean disPatchTouchEvent(MotionEvent ev){
  return onTouchEvent(ev);

2 一旦事件在传递链上被消费,后续的对象就无法接收该事件(和核心事件分发的伪代码一致)

3 如果onTouchEvent(ev)返回false,那么将传递给上一级的onTouchEvent(ev)

这个怎么理解呢?

  return (consume=Activity.disPatchTouchEvent(ev)= Window.disPatchTouchEvent(ev)
        = ViewGroup.disPatchTouchEvent(ev)= View.disPatchTouchEvent(ev))?true:false;

disPatchTouchEvent里面再来一段伪代码

boolean consume=false;
        if(onInterceptTouchEvent(ev)){
            consume=onTouchEvent(ev);
        }else {
            if (child.disPatchTouchEvent(ev)) {
                consume = true;
            }else {
                onTouchEvent(ev);
            }
        }
        return consume;

这里写图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值