参考:http://blog.csdn.net/wuseyukui/article/details/46523899
在上面这篇帖子里对于ViewGroup的部分我理解的很困难,然后我找了个帖子
首先说一下MotionEvent
MotionEvent中的事件:
ACTION_DOWN ——> 表示按下了屏幕
ACTION_MOVE ——> 表示移动手势
ACTION_UP ——> 表示离开屏幕
ACTION_CANCEL ——> 表示取消手势,一般由程序产生,不会由用户产生
所有事件都是从ACTION_DOWN开始
然后就到了触摸机制
面试的时候准备这个才发现,嗯activity也有触摸机制的
其中标注为yes的代表有此函数,为No的表示没有
而实际上activity的触摸机制是通过其内部包含的ViewGroup来实现的,唯一一点不同是它不能拦截
View中的传递
1、OnTouchListener不为null(即给view注册了OnTouchListener)——> 重写的onTouch()方法中返回false ——> 执行onTouchEvent方法 ——> 当前控件是ENABLED状态——> onClick()回调方法执行
2、OnTouchListener不为null ——> 重写的onTouch()方法返回true ——> onTouchEvent方法不执行 ——> onClick()回调方法不会执行
3、OnTouchListener为null ——> 执行onTouchEvent方法 ——> 当前控件是ENABLED状态——> onClick()回调方法执行
4、OnTouchListener为null ——> 执行onTouchEvent方法 ——> 当前控件不是ENABLED状态——> onClick()回调方法不会执行
也就是说当一个view被触摸了,先判断有没有OnTouchListener,有且onTouch返回true就被消费了,否则向下传递进入onTouchEvent,根据控件是否可用决定onclick是否执行
ViewGroup
他的三个函数最先触发的永远是dispatch,在遍立child时调用他们的分发直到view判断自己是否响应。
后来我想ViewGroup在理解上比View困难是因为他嵌套了View,因而显得复杂了,但其实就原则来说
dispatch只负责分发,最好的结果child返回true通过child的dispatch交给onTouchEvent处理
当viewGroup内部没有child接受,那只能自己响应了走自己的onTouchEvent
intercept负责拦截,当分发到某个ViewGroup,它表示自己要接受,通过intercept的返回值传给自己的o’nTouchEvent,但这有个问题就是分发的时候会确定一个target,拦截的时候这个target为null,这导致后续的action也是通过拦截获取到的,而不像正常处理时只分发一次
onTouchevent用于处理你的分发或者拦截的数据
viewGroup向下分发的原则是他自己不拦截,如果拦截不再分发。
贴一下别人的总结
1.Touch事件分发中只有两个主角:ViewGroup和View。ViewGroup包含onInterceptTouchEvent、dispatchTouchEvent、onTouchEvent三个相关事件。View包含dispatchTouchEvent、onTouchEvent两个相关事件。其中ViewGroup又继承于View。
2.ViewGroup和View组成了一个树状结构,根节点为Activity内部包含的一个ViwGroup。
3.触摸事件由Action_Down、Action_Move、Aciton_UP组成,其中一次完整的触摸事件中,Down和Up都只有一个,Move有若干个,可以为0个。
4.当Acitivty接收到Touch事件时,将遍历子View进行Down事件的分发。ViewGroup的遍历可以看成是递归的。分发的目的是为了找到真正要处理本次完整触摸事件的View,这个View会在onTouchuEvent结果返回true。
5.当某个子View返回true时,会中止Down事件的分发,同时在ViewGroup中记录该子View。接下去的Move和Up事件将由该子View直接进行处理。由于子View是保存在ViewGroup中的,多层ViewGroup的节点结构时,上级ViewGroup保存的会是真实处理事件的View所在的ViewGroup对象:如ViewGroup0-ViewGroup1-TextView的结构中,TextView返回了true,它将被保存在ViewGroup1中,而ViewGroup1也会返回true,被保存在ViewGroup0中。当Move和UP事件来时,会先从ViewGroup0传递至ViewGroup1,再由ViewGroup1传递至TextView。
6.当ViewGroup中所有子View都不捕获Down事件时,将触发ViewGroup自身的onTouch事件。触发的方式是调用super.dispatchTouchEvent函数,即父类View的dispatchTouchEvent方法。在所有子View都不处理的情况下,触发Acitivity的onTouchEvent方法。
7.onInterceptTouchEvent有两个作用:1.拦截Down事件的分发。2.中止Up和Move事件向目标View传递,使得目标View所在的ViewGroup捕获Up和Move事件。