在布局文件里,假设有3层 , 一层是button, textview等常见组件, 二层是嵌套的RelativeLayout, 三层是LinearLayout, 而一个触摸屏幕的事件无非就是ACTION_DOWN, ACTION_MOVE, ACTION_UP. 而手指从按下到松开离开屏幕, 其实事件分发的传递已经经过了这三层. 这里说下它的处理过程, 也算是巩固记忆了.
首先, dispatchTouchEvent(),onInterceptTouchEvent()和onTouchEvent() 这三个方法在每个view都会有, 而无论button,textview还是LinearLayout, RelativeLayout它们最终都继承于View, ViewGroup,因此 这三个方法它们各自都有. dispatchTouchEvent() 负责触摸屏幕事件(down - move - up)的分发, onInterceptTouchEvent()负责事件中的拦截, onTouchEvent()就是事件的处理了.
接着,来说说这三层中各自的三个方法如何参与了这个过程:
从Activity开始, 接收到手指按下屏幕的事件,即ACTION_DOWN, 最先到达LinearLayout, LinearLayout调用dispatchTouchEvent(), dispatchTouchEvent()一般不会用于重写, 它会自动分发给onInterceptTouchEvent(),如果onInterceptTouchEvent()的ACTION_DOWN 里面返回fasle就代表自己不处理这个事件,而是交给下一个去处理它,
于是继续把这个事件分发到下一层RelativeLayout, 同理RelativeLayout中如果onInterceptTouchEvent()的ACTION_DOWN依旧返回false的话, 就到达TextView这里. 当TextView的onInterceptTouchEvent())中返回true了 , 就代表由自己来处理这个事件, 也相当于拦截了这个事件.当处理完,返回true就将事件的处理结果逆向提交到Activity中, 告诉Activity自己处理好了. 然后接下来的ACTION_MOVE和ACTION_UP这两个事件才会继续传到TextView中并得到处理.
假如,刚开始的ACTION_DOWN在RelativeLayout就被处理掉 (即 RelativeLayout中的onInterceptTouchEvent()返回true,交由自己的onTouchEvent()去处理, 下层的TextView就无法参与这次触摸事件的传递分发, 后面的ACTION_MOVE和ACTION_UP, TextView也就无法得到传递).所以如果要拦截某一个TOUCH动作,就在onInterceptTouchEvent()动手吧(嘻嘻,这样说好理解一些嘛.)
只要拦截了ACTION_DOWN,后面的MOVE和UP事件都不会往下传递, 而只拦截MOVE事件, 则UP事件不再往下传递. 但无论是哪个View处理了这次的触摸事件, 其最后处理的结果都必须会逆向地提交到Activity中, 这样用户触摸屏幕的动作才会得到对应的反馈.