带你搞懂onInterceptTouchEvent和onTouchEvent

来源:互联网 发布:如何练形体气质知乎 编辑:程序博客网 时间:2024/04/29 09:17

今天被这个搞得有点晕,现在终于明白了,这个事件传递机制的详细过程。首先明确一些基本常识,我发现这些默认值不清楚是导致后面理解错误混乱的原因。1、onInterceptTouchEvent 为viewgroup独有,这个函数一般返回的是默认值是false。代表不拦截。好了,这个不拦截代表啥鸟意思呢?代表不拦截事件传递给子view。
2、事件其实分为三种,而不是一种。down,move,up。
3、每种事件如果按照正常的顺序是,(注意是每种事件)应该首先是dispatchTouchEventon,然后是IntercpetTounchEvent处理,然后向下传递给子view的dispatchTouchEvent,然后传递给子view的OnTouchEvent。 注意传递到这一步就是关键了。子view可以决定事件是否继续传递,关键就是看OntouchEvent的返回值是否为true。如果为true,这个事件(down,move,up)就不会传递了,这个事件到此为止。如果为false,继续传?传到哪儿去了呢,继续传给原来的viewgroup。传给viewgroup的OnTouchEvent事件了。如果它还不处理,那继续往上层的OnTouchEvent传递。谁要是处理,这个事件也结束了。
4、最终能够终止事件的只有OntouchEvent方法。类似onInterCeptTouchEvent,dispatchTouchEvent,是不能终止事件的,所以最终要有一个view或者viewgroup的OntouchEvent来终止,这个非常关键。
好了,写到这吧,有什么想法和意见可以评论提出来,欢迎交流,搞了这么久终于有点了解,关键就是事件的一种传递流向。把这种传递流向当做一种模型来看待。这样有助于理解这两个方法。
5、事件的传递是从group传递到子view一级一级的,但是事件的消费确实从最里面的子view开始,这点值得重视。
6、对于DispatchTouchEvent如果在down事件的时候返回了false,代表了并没有处理down事件,那么后续的move事件,up事件也不会传过来。onInterceptTouchEvent也是如此,如果down事件返回值为false,那么move和up事件还会再传给这个方法,然后再传给目标view的onTouchEvent。如果该方法的down事件返回true,那么后续的down和up事件就是不会再传给该方法了,而是直接传递给该层的onTouchEvent处理了。
7、经过试验,对于拦截事件方法onInterceptTouchEvent和事件分发方法DispatchTouchEvent。拦截事件效果有非常不一样的地方。onInterceptTouchEvent专业拦截事件方法,可以拦截down,move,和up都可以拦截,阻止其向下传递。比如说down事件返回ture之后,下层的view就都不会收到任何事件。如果move事件拦截的话,第一次下层view的down事件会接收,但是move事件就不会接收了。但是dispatchtouchevent方法确只能拦截down事件,move事件确不能拦截,也就是说如果down事件拦截的话,move事件和up事件都不会传递到这个方法了,但是如果move事件拦截的话,up事件任然会来到这个方法。没法去搞源码了,那个太复杂,这个是通过实验得来的。有了以上的知识,可以对处理事件冲突就胸有成竹了。
8、发现一个有趣的现象,假设一个down事件被子view消耗掉,但是move事件被上层group拦截掉,但是该子view会受到一个action_cancel的事件。这个现象说明了一个原理。就是如果down事件消费掉后,不管怎么拦截总会有一个action_cancel或者action_up事件。或者说down事件,move事件,up事件必须作为一套整体被某个view消费,如果分开不同的view,就会导致action_cancel产生。这个结论只是现象说明,有哪位如果看到这个源码解释,可以告诉我一下,谢谢。

2 0