android TouchEvent 事件处理流程学习

1.  怎么做到当路径上有一个ViewGroup拦截了Down事件之后,后续的move , up等事件就只交给它来处理,  而不会再继续往下走了?

2.  个中主流控件, 包括FrameLayout, RelatvieLayout, LinearLayout, 等都是如何实现其 onTouchEvent, onInterceptTouchEvent, dispatchTouchEvent方法的.?"

有什么共性?   有什么区别?

-----上面提到的三个布局都没有实现任何一个方法, 都是集成的ViewGroup中的逻辑,   而他们的直接父类, ViewGroup 也只实现了onInterceptTouchEvent() 和dispatchTouchEvent()

并且onInterceptTouchEvent()中基本上就是返回false,( 除了是鼠标拖动滚动条的事件).

所以基本上, 分析的重点就在View.java和ViewGroup.java中的dispatchTouchEvent()方法.

ScrollView  实现了自己的onInterceptTouchEvent()onTouchEvent()    注意ScrollView 继承了FrameLayout, 只支持竖向

onInterceptTouchEvent() 注释说的明白: 我们只关心当前是不是正在被滑动(dragging).

从实际效果上, 不管承载的控件们是否拦截或者处理了touchEvent, ScrollView本身都是会相应滑动的.

只要是move事件, 判断出滑动距离超过touchSlop之后,  就认为是在dragging. 那么就会返回true, 后续的事件都会自行处理.并且从这个返回true的事件开始, 会给子控件一个cancel.

再重申一遍重点:

只有在move事件中, 并且当累计滑动距离(初始位置是在down时记录的)已经超过了touchSlop了,  那么就会对子控件发出cancel事件, 对父控件调用:requestDisallowInterceptTouchEvent(true), 通知父亲控件, 不要瞎掺和了.

上面说的的对子控件发出cancel事件是怎么做到的?  在这个事件的处理流程上, dispatchTouchEvent()中, 先调用自身的onInterceptTouchEvent()判断自身是否拦截, 如上面分析, 如果拦截, 那么下面的intercepted变量为true, 所以接下来调用dispatchTransformedTouchEvent()时, cancelChild参数为true, 里面会生成cancel事件, 并交给子控件处理.  并且有一点注意:对于这个子控件, 处理完cancel事件之后, 后续的move, up事件也不会再交给它处理了.   中断了,  跟它没关系了,

android TouchEvent 事件处理流程学习_第1张图片


问题: 那么上面说的这点又是怎么做到的呢:  怎么才做到cancel之后, 后续的事件都不给这个子控件了?


android TouchEvent 事件处理流程学习_第2张图片

上面这个段代码中高亮选中部分,  会在子控件处理完cancel之后, 把mFirstTouchTarget置为null. 因为对于ScrollView, 只有一个子控件, 所以next为null.

mFirstTouchTarget变成了null, 那下一次进入dispatchTouchEvent()后, 处理就简单多了, 见下面代码段:


android TouchEvent 事件处理流程学习_第3张图片

对于之后的move事件, 并且mFirstTouchTarget已经为null,  直接设置intercepted为true.   同时后面的流程也就不再调用子控件的dispatchTouchEvent()

AbsListView 实现了自己的onInterceptTouchEvent()onTouchEvent()


----------未完

你可能感兴趣的:(android TouchEvent 事件处理流程学习)