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事件也不会再交给它处理了. 中断了, 跟它没关系了,
问题: 那么上面说的这点又是怎么做到的呢: 怎么才做到cancel之后, 后续的事件都不给这个子控件了?
上面这个段代码中高亮选中部分, 会在子控件处理完cancel之后, 把mFirstTouchTarget置为null. 因为对于ScrollView, 只有一个子控件, 所以next为null.
mFirstTouchTarget变成了null, 那下一次进入dispatchTouchEvent()后, 处理就简单多了, 见下面代码段:
对于之后的move事件, 并且mFirstTouchTarget已经为null, 直接设置intercepted为true. 同时后面的流程也就不再调用子控件的dispatchTouchEvent()
AbsListView 实现了自己的onInterceptTouchEvent()onTouchEvent()
----------未完