先看一下ViewGroup的dispatchTouchEvent的关键源码:

public boolean dispatchTouchEvent(MotionEvent ev) {...        if (action == MotionEvent.ACTION_DOWN) {...           if (disallowIntercept || !onInterceptTouchEvent(ev)) {                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) {                       ...                            if (child.dispatchTouchEvent(ev))  {                                // Event handled, we have a target now.                                mMotionTarget = child;                                return true;                            }                    }                }            }        }...        final View target = mMotionTarget;        if (target == null) {...            return super.dispatchTouchEvent(ev);        }        if (!disallowIntercept && onInterceptTouchEvent(ev)) {            ...            if (!target.dispatchTouchEvent(ev)) {                // target didn't handle ACTION_CANCEL. not much we can do                // but they should have.            }            // clear the target            mMotionTarget = null;            // Don't dispatch this event to our own view, because we already            // saw it when intercepting; we just want to give the following            // event to the normal onTouchEvent().            return true;        }...        return target.dispatchTouchEvent(ev);    }
根据以上代码可知,如果onInterceptTouchEvent方法返回true,会直接调用当前ViewGroup的onTouch方法,否则则会依次调用其内包含的子控件的dispatchTouchEvent方法。我写了一个测试用例,ViewGroup的onInterceptTouchEvent方法与所有View的onTouch方法都打了Log:
<?xml version="1.0" encoding="utf-8"?><org.gavin.test.view.MyScrollView xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="fill_parent"    android:layout_height="fill_parent" ><org.gavin.test.view.MyLinearLayout    android:layout_width="fill_parent"    android:layout_height="fill_parent"    android:orientation="vertical">    <org.gavin.test.view.MyImageView        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:src="@drawable/ic_launcher"></org.gavin.test.view.MyImageView></org.gavin.test.view.MyLinearLayout></org.gavin.test.view.MyScrollView>
Log信息:

I/MyScrollView(26001): onInterceptTouchEvent:MotionEvent{404ea7c8 action=0 x=34.215885 y=51.963867 pressure=0.14117648 size=0.1}
I/MyLinearLayout(26001): onInterceptTouchEvent:MotionEvent{404ea7c8 action=0 x=34.215885 y=51.963867 pressure=0.14117648 size=0.1}
I/MyImageView(26001): onTouchEvent:MotionEvent{404ea7c8 action=0 x=34.215885 y=51.963867 pressure=0.14117648 size=0.1}
I/MyLinearLayout(26001): onTouchEvent:MotionEvent{404ea7c8 action=0 x=34.215885 y=51.963867 pressure=0.14117648 size=0.1}
I/MyScrollView(26001): onTouchEvent:MotionEvent{404ea7c8 action=0 x=34.215885 y=51.963867 pressure=0.14117648 size=0.1}

如果MyLinearLayout的onInterceptTouchEvent方法返回true:

11-04 14:05:08.389: I/MyScrollView(26297): onInterceptTouchEvent:MotionEvent{404e9ed0 action=0 x=24.439919 y=41.980873 pressure=0.13333334 size=0.15}
11-04 14:05:08.389: I/MyLinearLayout(26297): onInterceptTouchEvent:MotionEvent{404e9ed0 action=0 x=24.439919 y=41.980873 pressure=0.13333334 size=0.15}
11-04 14:05:08.397: I/MyLinearLayout(26297): onTouchEvent:MotionEvent{404e9ed0 action=0 x=24.439919 y=41.980873 pressure=0.13333334 size=0.15}
11-04 14:05:08.397: I/MyScrollView(26297): onTouchEvent:MotionEvent{404e9ed0 action=0 x=24.439919 y=41.980873 pressure=0.13333334 size=0.15}

OK,再看这段代码:

if (child.dispatchTouchEvent(ev))  {                                // Event handled, we have a target now.                                mMotionTarget = child;                                return true;                            }
从这段代码可以看出,如果某个子控件的dispatchTouchEvent方法返回true,则中断以后的消息传递。并在下一个非ACTION_DOWN事件直接调用此子控件的dispatchTouchEvent方法。一个View的dispatchTouchEvent返回true,主要可能是onTouch方法返回true。如果我们把MyImageView的onTouchEvent返回值改为true:

I/MyScrollView(26393): onInterceptTouchEvent:MotionEvent{404eb2b0 action=0 x=32.749493 y=51.05632 pressure=0.11764707 size=0.1}
/MyLinearLayout(26393): onInterceptTouchEvent:MotionEvent{404eb2b0 action=0 x=32.749493 y=51.05632 pressure=0.11764707 size=0.1}
I/MyImageView(26393): onTouchEvent:MotionEvent{404eb2b0 action=0 x=32.749493 y=51.05632 pressure=0.11764707 size=0.1}

更多相关文章

  1. Android自定义dialog简单实现方法
  2. Android中发短信的代码
  3. android使用sharedPreferences()方法读写文件操作
  4. android studio 代码混淆
  5. Android getWindow().setFlags方法 设置窗体全屏点亮背景模糊 &&
  6. Android 混淆代码的时候出现问题
  7. Android:Activity中onCreate方法的参数及用途
  8. 有关android安全性的问题--代码混淆
  9. Android NDK so crash,定位目标代码使用

随机推荐

  1. ubuntu下搭建cordova开发环境
  2. android获得圆角图片
  3. Multitasking the android way
  4. Android 列表对话框
  5. android背景自动伸缩
  6. Android应用程序设置Home Screen
  7. android dialog集合
  8. Android Add new target
  9. Android 清理app所有缓存
  10. Android Getting Started