网上已经有很多关于事件传递的帖子了,我这边挑一篇写的不错的,供大家参考,http://www.360doc.com/content/13/0503/16/7857928_282701201.shtml
为了方便大家理解,我自己画了一个示意图,来方便大家理解记忆:
ViewGroup关于touch事件的处理有三个方法:dispatchEvent,onInterceptTouchEvent,onTouchEvent
View关于touch的事件处理有两个方法:dispatchEvent,onTouchEvent
1. 那么我们如何判断该在哪个代码里处理我们的touch事件呢?
其实不难看出来按事件的传递,只要可以传到该层,则肯定会调用dispatchEvent事件。也就是说我们在必须运行的代码应该放到dispatchEvent中。
而决定我们是否拦截本次touch事件就在onInterceptTouchEvent中写了。
onTouchEvent是整体的最终的逻辑处理。
2.事件传递过程中,如果我的Touch事件传递到ViewGroupA时,onInterceptTouchEvent方法返回了true,后续的move和up事件就不会再往ViewGroupB中传递了,这个时候如果我们希望它接下来把move和up事件传递到ViewGroupB中时该如何处理?
这种情况会在什么时候遇到呢?比如我们界面下拉上边是一个Title图,下边是listView,比如58同城的app中,首页向上滚动时,显示title图片慢慢收起来,接下来是下边的列表页向上滚动,这样就涉及到了touch事件在传递时的中断处理。我们如何让touch事件的对象发生变化呢?
答案就是我们需要手动的制造一次新的down事件。
private void sendDownEvent() { if (DEBUG) { PtrCLog.d(LOG_TAG, "send down event"); } final MotionEvent last = mLastMoveEvent; MotionEvent e = MotionEvent.obtain(last.getDownTime(), last.getEventTime(), MotionEvent.ACTION_DOWN, last.getX(), last.getY(), last.getMetaState()); dispatchTouchEventSupper(e); }
在onTouchEvent的
MotionEvent.
ACTION_MOVE对应的处理中,当判断到达临界值时,则可以发送上边的downEvent,来从新走一遍touch流程,让ViewGroupB的onInterceptTouchEvent方法拦截到新制造的这次touch事件,返回为true,这样就完成了整体拖拽过程中touch事件由一个控件传递到另一个控件的需求。