现有ViewGroupA,ViewGroupB,View,布局中的嵌套关系是ViewGroupA为最外层的父控件,ViewGroupB是其下面的子控件,View则为ViewGroupB下面的子控件。
对于ViewGroup来说,可以重写一下三个方法:
@Override public boolean dispatchTouchEvent(MotionEvent ev) { return super.dispatchTouchEvent(ev); } @Override public boolean onInterceptTouchEvent(MotionEvent ev) { return super.onInterceptTouchEvent(ev); } @Override public boolean onTouchEvent(MotionEvent event) { return super.onTouchEvent(event); }
对于View来说,可以重写下面两个方法(没有onInterceptTouchEvent):
@Override public boolean dispatchTouchEvent(MotionEvent event) { return super.dispatchTouchEvent(event); } @Override public boolean onTouchEvent(MotionEvent event) { return super.onTouchEvent(event); }
现在,点击一下view,代码不做任何修改时事件是这样传递的:
ViewGroupA dispatchTouchEvent
ViewGroupA onInterceptTouchEvent
ViewGroupB dispatchTouchEvent
ViewGroupB onInterceptTouchEvent
View dispatchTouchEvent
View onTouchEvent
ViewGroupB onTouchEvent
ViewGroupA onTouchEvent
可以看出,事件向下层传递是通过dispatchTouchEvent和onInterceptTouchEvent,到底后再通过onTouchEvent向上传递至最外层,率先响应view点击事件的是最外层的ViewGroupA的dispatchTouchEvent,但是做拦截事件一般不会在dispatchTouchEvent方法中处理,而是在onInterceptTouchEvent方法中处理,如何处理呢,很简单,返回值为true则不会再往下传递(默认是false),这里需要注意的是,在onInterceptTouchEvent中做了拦截处理后,虽然不会再往下继续传递,但是还要往上传递回最外层的,举个例子:
如果在ViewGroupB的onInterceptTouchEvent做了拦截(即返回true)后,事件传递顺序如下:
ViewGroupA dispatchTouchEvent
ViewGroupA onInterceptTouchEvent
ViewGroupB dispatchTouchEvent
ViewGroupB onInterceptTouchEvent
ViewGroupB onTouchEvent
ViewGroupA onTouchEvent
另外,当在onTouchEvent做拦截事件即返回true)时,则事件传递到此为止,不会再往上传递了,例如:
View的onTouchEvent返回true,则事件传递顺序:
ViewGroupA dispatchTouchEvent
ViewGroupA onInterceptTouchEvent
ViewGroupB dispatchTouchEvent
ViewGroupB onInterceptTouchEvent
View dispatchTouchEvent
View onTouchEvent
ViewGroupB 的onTouchEvent返回true,则事件传递顺序:
ViewGroupA dispatchTouchEvent
ViewGroupA onInterceptTouchEvent
ViewGroupB dispatchTouchEvent
ViewGroupB onInterceptTouchEvent
View dispatchTouchEvent
View onTouchEvent
ViewGroupB onTouchEvent
那么,到此为止,懂了么