本文是看了http://blog.youkuaiyun.com/morgan_xww/article/details/9372285/ 这篇文章后,再结合自己理解所做的一个记录。
在处理touchEvent的时候,与之相关的3个方法:
public boolean dispatchTouchEvent (MotionEvent ev); //用于向子控件分派事件,返回ture不分派,返回false则分派。
public boolean onInterceptTouchEvent (MotionEvent ev); //用于拦截事件,阻止事件向子控件传递,返回true则拦截,返回false则不拦截。
public boolean onTouchEvent (MotionEvent ev); //用于控件处理事件,返回true则表示该层控件处理事件成功,此事件中无需再调用父控件的 //onTouchEvent方法,返回false则表示该层控件未成功处理事件,需要传递至父控件,
//调用父控件的onTouchEvent方法。
拥有这三个方法的相关类:
Activity类 | Activity | dispatchOnTouchEvent(); onTouchEvent(); |
ViewGroup及其子类 | FragmentLayout、LinearLayout、ListView、GridView... | dispatchTouchEvent(); onInterceptTouchEvent(); onTouchEvent(); |
View控件 | Button,TextView,EditText,.... | dispatchTouchEvent(); onTouchEvent(); |
三个方法的用法:
dispatchTouchEvent() | 用来分派事件。 其中调用了onInterceptTouchEvent()和onTouchEvent(),一般不重写该方法 |
onInterceptTouchEvent() | 用来拦截事件。 ViewGroup类中的源码实现就是{return false;}表示不拦截该事件, 事件将向下传递(传递给其子View); 若手动重写该方法,使其返回true则表示拦截,事件将终止向下传递, 事件由当前ViewGroup类来处理,就是调用该类的onTouchEvent()方法 |
onTouchEvent() | 用来处理事件。 返回true则表示该View能处理该事件,事件将终止向上传递(传递给其父View); 返回false表示不能处理,则把事件传递给其父View的onTouchEvent()方法来处理 |
touchEvent的处理过程:
当touchEvent出现后,处理过程分为两部分:捕获和处理,
获捕:在默认情况下,先由顶层控件捕获Event,在逐层传递至最底层控件(例如:activity—>ViewGroup—>View)
处理:处理Event则是在捕获过程完成后,从捕获了该Event的最底层控件开始处理,处理成功则不再往上传递,处理不成功则向父控件传递事件,逐层往上调用相应的
onTouchEvent处理直至顶层。(View—>ViewGroup—>activity)
与touchEvent处理相关的一些点:
1) 这一系列的传递过程都由dispatchOnTouchEvent()控制,在不人为干预的情况下,Event由上至下依层传递,传至最底层的View后,由最底层的onTouchEvent方法首先处理事件,处理成功则返回true,处理失败则返回false,处理成功则终止往上传递,处理失败则继续往上层传递,依层调用相应的onTouchEvent()。
2)经过人为的干预后,向下传递的过程被拦截在调用onInterceptTouchEvent返回true的相应层,这时则不会继续往下传递,而是调用相应层的onTouchEvent()处理事件,处理成功则终止,处理失败则向上传递。】
3)
另外,dispatchTouchEvent()方法中还有“记忆”的功能,如果第一次事件向下传递到某View,它把事件继续传递交给它的子View,它会记录该事件是否被它下面的View给处理成功了,(怎么能知道呢?如果该事件会再次被向上传递到我这里来由我的onTouchEvent()来处理,那就说明下面的View都没能成功处理该事件);当第二次事件向下传递到该View,该View的dispatchTouchEvent()方法机会判断,若上次的事件由下面的view成功处理了,那么这次的事件就继续交给下面的来处理,若上次的事件没有被下面的处理成功,那么这次的事件就不会向下传递了,该View直接调用自己的onTouchEvent()方法来处理该事件。
4)“记忆”功能的信息只在一系列事件完成之前有效,如从ACTION_DOWN事件开始,直到后续事件ACTION_MOVE,ACTION_UP结束后,“记忆”的信息就会清除。也就是说如果某View处理ACTION_DOWN事件失败了(onTouchEvent()返回false),那么后续的ACTION_MOVE,ACTION_UP等事件就不会再传递到该View了,由其父View自己来处理。在下一次发生ACTION_DOWN事件的时候,还是会传递到该View。
onTouchEvent()和onTouch()
除了onTouchEvent()用于处理touchEvent,还可以实现OnTouchListener接口,重写onTouch方法来处理touch事件,onTouch()方法优先级高于 onTouchEvent()。同时存在的情况下优先调用onTouch(),onTouch()返回true则不会再调用onTouchEvent()返回false才代表事件处理不成功,调用onTouchEvent。