参考博客:http://www.cnblogs.com/sunzn/archive/2013/05/10/3064129.html
http://blog.csdn.net/guolin_blog/article/details/9097463
http://blog.csdn.net/guolin_blog/article/details/9153747
建议三篇文章一起看
view
dispatchTouchEvent(){
if(onTouchListener != null && isCleable && view.onTouch()){
return true;
}
return onTouchEvent();
}
如果onTouchEvent 返回 false 那么 当前view的 dispatchTouchEvent也会返回false 则 会在父dispatchTouchEvent 中调用 onTouchEvent
说到这里,很多的朋友肯定要有巨大的疑问了。这不是在自相矛盾吗?前面的例子中,明明在onTouch事件里面返回了false,
ACTION_DOWN和ACTION_UP不是都得到执行了吗?其实你只是被假象所迷惑了,让我们仔细分析一下,在前面的例子当中,
我们到底返回的是什么。
参考着我们前面分析的源码,首先在onTouch事件里返回了false,就一定会进入到onTouchEvent方法中,然后我们来看一下
onTouchEvent方法的细节。由于我们点击了按钮,就会进入到第14行这个if判断的内部,然后你会发现,不管当前的action是什么,
最终都一定会走到第89行,返回一个true。
是不是有一种被欺骗的感觉?明明在onTouch事件里返回了false,系统还是在onTouchEvent方法中帮你返回了true。就因为这
个原因,才使得前面的例子中ACTION_UP可以得到执行。
onTouch() = true ;
则 dispatchTouchEvent() = true ;
则 当前view的 dispatchTouchEvent() 则事件将有 dispatchTouchEvent进行消费
onTouch = false ;
则 会执行onTouchEvent();
如果当前view 可点击 则直接交由当前view的onTouchEvent进行处理 则 dispatchTouchEvent = true;
如果当前view 不可点击 则直接返回false 则 dispatchTouchEvent = false; 则由外层父view的onTouchEvent()进行消费
onInterreceptTouchEnvent(){
return true / false;
}
如果为true 则表示将事件进行拦截 并将拦截的时间交给当前view的onTouchEvent()
对于 onInterceptTouchEvent 如果返回 false 就会进入判断 然后遍历子view 并调用子view的 onInterceptTouchEvent 如果子view的 disallowIntercept返回true
则 该view的 dispatchTouchEvent 返回 true(不确定) 如果 dispatchTouchEvent = false 则表示此事件向上传递给父view
dispatchTouchEvent(){
if (disallowIntercept || !onInterceptTouchEvent(ev)) {
ev.setAction(MotionEvent.ACTION_DOWN);
final int scrolledXInt = (int) scrolledXFloat;
final int scrolledYInt = (int) scrolledYFloat;
final View[] children = mChildren;
final int count = mChildrenCount;
for (int i = count - 1; i >= 0; i--) {
final View child = children[i];
if ((child.mViewFlags & VISIBILITY_MASK) == VISIBLE
|| child.getAnimation() != null) {
child.getHitRect(frame);
if (frame.contains(scrolledXInt, scrolledYInt)) {
final float xc = scrolledXFloat - child.mLeft;
final float yc = scrolledYFloat - child.mTop;
ev.setLocation(xc, yc);
child.mPrivateFlags &= ~CANCEL_NEXT_UP_EVENT;
if (child.dispatchTouchEvent(ev)) {
mMotionTarget = child;
return true;
}
}
}
}
}
}