Touch事件分发中只有两个主角:ViewGroup和View。Activity的Touch事件事实上是调用它内部的ViewGroup的Touch事件,可以直接当成ViewGroup处理(对于每个Activity
都有 setContentView()来设置它的布局,而setContentView()设置的布局肯定会有一个ViewGroup作为该布局的根节点,所以直接处理该ViewGroup)
。 ViewGroup的相关事件有三个:dispatchTouchEvent、onInterceptTouchEvent、onTouchEvent;View的相关事件只有两个:dispatchTouchEvent、onTouchEvent(原因:Button
就是一个View,Button已经是一个最小单元了,在Button里边不会再包含其他控件,所以也就不需要拦截事件的方法 onInterceptTouchEvent())
。 Touch事件处理机制:当接收到一个Touch事件时,流程:touch发生 --> Activity的dispatchTouchEvent() --> 最顶层的父View(ViewGroup)中的dispatchTouchEvent()
方法,开始分发事件(在ViewGroup类中就已经实现了dispatchTouchEvent()方法),然后执行父View(ViewGroup)中的onInterceptTouchEvent()方法,判断是否中断
事件(ViewGroup中的onInterceptTouchEvent()直接返回false,表示不拦截;在LinearLayout...这些类中没有重写onInterceptTouchEvent()):
1. 如果onInterceptTouchEvent返回true,则中断此事件,调用当前父View(ViewGroup)中的onTouchEvent(),
如果onTouchEvent() 返回true,消耗此事件,处理事件;如果返回false,不处理事件,向上传递
2. 如果onInterceptTouchEvent返回false,自己不处理,调用子View(View | ViewGroup)中的dispatchTouchEvent()方法,将事件传递给子View(View | ViewGroup),处理同上...
3. 当传递到最底层的子View(extends View)时,由于View中并没有onInterceptTouchEvent()方法,所以会直接调用View中的onTouchEvent(),如果返回true,
消耗此事件,处理事件;如果返回false,不处理事件,向上传递,调用父View(View | ViewGroup) 中的onTouchEvent()
4. 有一个方法可以阻止父层的View截获touch事件,就是调用getParent().requestDisallowInterceptTouchEvent(true);方法。一旦底层View收到touch的action后
调用这个方法那么父层View就不会再调用onInterceptTouchEvent()了,也无法截获以后的action
5. 小结:对于Touch事件,可以把点击(触摸)一个View分成两部分:第一部分是从顶层的ViewGroup到被触摸的View,第二部分是从被触摸的View返回到ViewGroup
第一部分:对于第一部分,就是从上(外)向下(里)的过程,这个过程中只有ViewGroup、View对该Touch事件的分发(dispatchTouchEvent)和
拦截(onInterceptTouchEvent),并没有处理(onTouchEvent)
第二部分:如果经过第一部分的整个过程,Touch事件顺利传递到了被触摸的View,此时才开始了对Touch事件的处理(onTouchEvent),如果该View在自己
的onTouchEvent()中返回了false(没有消耗事件),事件将会回传(从该View再到顶层的ViewGroup),回传的一路就是处理事件的过程(依次调用
View或ViewGroup的onTouchEvent()方法,直到事件被消耗)
都有 setContentView()来设置它的布局,而setContentView()设置的布局肯定会有一个ViewGroup作为该布局的根节点,所以直接处理该ViewGroup)
。 ViewGroup的相关事件有三个:dispatchTouchEvent、onInterceptTouchEvent、onTouchEvent;View的相关事件只有两个:dispatchTouchEvent、onTouchEvent(原因:Button
就是一个View,Button已经是一个最小单元了,在Button里边不会再包含其他控件,所以也就不需要拦截事件的方法 onInterceptTouchEvent())
。 Touch事件处理机制:当接收到一个Touch事件时,流程:touch发生 --> Activity的dispatchTouchEvent() --> 最顶层的父View(ViewGroup)中的dispatchTouchEvent()
方法,开始分发事件(在ViewGroup类中就已经实现了dispatchTouchEvent()方法),然后执行父View(ViewGroup)中的onInterceptTouchEvent()方法,判断是否中断
事件(ViewGroup中的onInterceptTouchEvent()直接返回false,表示不拦截;在LinearLayout...这些类中没有重写onInterceptTouchEvent()):
1. 如果onInterceptTouchEvent返回true,则中断此事件,调用当前父View(ViewGroup)中的onTouchEvent(),
如果onTouchEvent() 返回true,消耗此事件,处理事件;如果返回false,不处理事件,向上传递
2. 如果onInterceptTouchEvent返回false,自己不处理,调用子View(View | ViewGroup)中的dispatchTouchEvent()方法,将事件传递给子View(View | ViewGroup),处理同上...
3. 当传递到最底层的子View(extends View)时,由于View中并没有onInterceptTouchEvent()方法,所以会直接调用View中的onTouchEvent(),如果返回true,
消耗此事件,处理事件;如果返回false,不处理事件,向上传递,调用父View(View | ViewGroup) 中的onTouchEvent()
4. 有一个方法可以阻止父层的View截获touch事件,就是调用getParent().requestDisallowInterceptTouchEvent(true);方法。一旦底层View收到touch的action后
调用这个方法那么父层View就不会再调用onInterceptTouchEvent()了,也无法截获以后的action
5. 小结:对于Touch事件,可以把点击(触摸)一个View分成两部分:第一部分是从顶层的ViewGroup到被触摸的View,第二部分是从被触摸的View返回到ViewGroup
第一部分:对于第一部分,就是从上(外)向下(里)的过程,这个过程中只有ViewGroup、View对该Touch事件的分发(dispatchTouchEvent)和
拦截(onInterceptTouchEvent),并没有处理(onTouchEvent)
第二部分:如果经过第一部分的整个过程,Touch事件顺利传递到了被触摸的View,此时才开始了对Touch事件的处理(onTouchEvent),如果该View在自己
的onTouchEvent()中返回了false(没有消耗事件),事件将会回传(从该View再到顶层的ViewGroup),回传的一路就是处理事件的过程(依次调用
View或ViewGroup的onTouchEvent()方法,直到事件被消耗)