android开发:探索学习Android Touch事件分发传递机制(一)

一 :先贴个"点击事件"分发流程图:

点击事件分发流程如下:

1.当我我们点击屏幕时,触发Activity的dispatchTouchEvent()方法,如果它返回true或者false则代表事件被消费(不再传递),返回super()时则会传到ViewGroup的dispatchTouchEvent()方法。

2.当ViewGroup的dispatchTouchEvent()方法返回true时,代表事件被消费。如果返回false则会把该事件返回到Activity的onTouchEvent()方法进行处理,返回super()则事件传递到ViewGroup的onInterceptTouchEvent()方法,onInterceptTouchEvent()返回true代表拦截该事件,则把事件交给ViewGroup的onTouchEvent()方法处理,如果它返回的是false或者super(),则代表不拦截该事件,所以事件会传递到View的dispatchTouchEvent()

3.当view的dispatchTouchEvent()返回true时同样代表事件被消费,返回false则事件会传递到ViewGroup的onTouchEvent(),返回super()事件传递到View的onTouchEvent()方法,onTouchEvent()返回ture代表事件被消费,返回false则事件传递回上一层的onTouchEvent();

二:接下来我们来做个demo验证一下流程:

自定义一个viewGroup

自定义一个view

在布局文件中viewGroup包含view

activity和view重写dispatchTouchEvent()和onTouchEvent(),viewGroup重写dispatchTouchEvent()和onInterceptTouchEvent()和onTouchEvent(),每个方法都打上log,返回值都是默认的。

UI效果如下:

 

1.当我点击View的时候log输出是这样的:

红色框代表点击事件的分发路径,黑色框代表触摸事件的分发路径(因为一般点击事件后面都会带有一个以上的触摸事件):

我们看到点击事件的分发路径是一个U字形,事件一路从activity传下来到view,然后view再一路传回去。最后在Activity的onTouchEvent()方法中消费。

而黑色框代表点击事件后伴随的触摸事件,它由Activity的dispatchTouchEvent()触发后直接到onTouchEvent();

为什么会这样呢,为什么它不像点击事件一样走完所有流程呢????这个后面我们会来讲解,因为触摸事件跟点击事件的消费有关

2.当我们修改View的onTouchEvent()返回值==true时,Log日志是这样的:

点击事件一路分发下来,到view的onTouchEvent()停止传递,事件被消费。然后再来看触摸事件,分发路径是一样。

3.当我们修改ViewGroup的onInterceptTouchEvent()和onTouchEvent()返回值为true时,Log日志:

ViewGrounp的onInterceptTouchEvent()和onTouchEvent()返回值为true时,代表拦截事件,并在自身的onTouchEvent()中消费,所以onInterceptTouchEvent()==true时代表拦截,点击事件不会向下传递,而是交到了自身的onTouchEvent(),黑色框代表后续的触摸事件,我们看到它走到ViewGroup的dispatchTouchEvent()后直接转到onTouchEvent()。为什么和第一个例子不一样了?

4.当ViewGroup的onTouchEvent()返回值为true,其他方法都是默认时,日志如下:

因为viewGroup的onInterceptTouchEvent()默认是不拦截的,所以点击事件一路从activity分发到view,view没有进行消费,最后事件由view返回到viewGroup的onTouchEvent(),然后停止消费。

触摸事件从activity分发到viewGroup的dispatchTouchEvent()后也是直接转到onTouchEvent(),分发路径和上面的第三个例子一样。

三:总结

点击事件对于dispatchTouchEvent()方法:

1.return true:消费掉事件,终止传递。

2.return false: 将事件传递给上一级View的onTouchEvent()方法。如果是Activity的dispatchTouchEvent()方法,则也是消费掉事件,终止传递。

3.return super:如果是Activity,则传给下一级view(viewGroup)的dispatchTouchEvent;如果是ViewGroup,则传给自己的onInterceptTouchEvent();如果是View,则传给自己的onTouchEvent().


点击事件对于onInterceptTouchEvent()方法:

1.return true:将事件传递给ViewGroup自己的onTouchEvent()方法处理。

2.return false/super:将事件传递给下一级View的dispatchTouchEvent()。

3.onInterceptTouchEvent()方法是viewGrounp特有的

点击事件对于onTouchEvent()方法:

1.return true:消费掉事件,终止传递。

2.return false/super:将事件传递给上一级view的onTouchEvent()方法。

3.Activity的onTouchEvent()方法不管返回什么都会终止事件

触摸事件: 

1.由例子1得出:点击事件在activity中的方法被消费,触摸事件也会被在activity中消费,并且不会走点击事件的分发流程,而是直接抄近路。

2.点击事件是在viewGroup中的方法被消费,那么触摸事件也会被在viewGroup中消费,并且会跳过viewGroup的onInterceptTouchEvent()方法,像例子3、4,虽然点击事件的分发路径不一样,但是最后都是在viewGroup的onTouchEvent()消费,因此他们的触摸事件也是在onTouchEvent()消费,并且也是抄近路。

3.点击事件是在view中的方法被消费,那么触摸事件在view中消费,分发路径和点击事件一样

一直网上看了很多篇文章,写的都不是很好,特别是画图画的云里雾里,看都看不懂。最后发现掘金有篇文章写的不错:

https://juejin.im/post/5a0fab1bf265da432d27ad70

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值