Android中view的Touch事件传递顺序
2012-11-23 00:00
633 查看
先看一下ViewGroup的dispatchTouchEvent的关键源码:
根据以上代码可知,如果onInterceptTouchEvent方法返回true,会直接调用当前ViewGroup的onTouch方法,否则则会依次调用其内包含的子控件的dispatchTouchEvent方法。我写了一个测试用例,ViewGroup的onInterceptTouchEvent方法与所有View的onTouch方法都打了Log:
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,再看这段代码:
从这段代码可以看出,如果某个子控件的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}
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}
相关文章推荐
- Android对touch事件的拦截,在View Tree上的传递顺序
- Android View Touch事件传递机制
- android事件分析(二)——MOTIONEVENT事件在ONINTERCEPTTOUCHEVENT()、ONTOUCHEVENT()中的传递顺序
- Android中事件分发处理MotionEvent事件在onInterceptTouchEvent()、onTouchEvent()中的传递顺序【转】
- Mark 下 android Touch 事件传递顺序
- Android Touch事件传递机制全面解析(从WMS到View树)
- Android---Touch事件的传递机制 & Viewpager和View的事件相应规则
- Android中ViewGroup到View的Touch事件的传递机制
- 深入探索Android 中view的touch事件传递
- Android 之在View以及ViewGroup中Touch事件传递
- Android View touch事件传递方式规律
- Android事件传递机制以及ViewGroup的onInterceptTouchEvent的理解
- 从源码角度带你分析 Android View 事件分发 dispatchTouchEvent,onTouch,onTouchEvent,onClick逻辑顺序过程(一)
- Android Touch事件在View层级结构中的传递机制
- Android touch事件传递及View的绘制流程
- android中TouchEvent事件传递之普通view之间
- 菜鸟学android——touch事件的传递顺序
- 【Android View】Android中View对触摸事件的处理和传递dispatchTouchEvent、onInterceptTouchEvent
- android touch event事件的传递顺序。
- Android Touch事件传递机制全面解析(从WMS到View树)