main.xml
<?xml version="1.0" encoding="utf-8"?> <cn.sunzn.tevent.TouchEventFather xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:background="#468AD7" android:gravity="center" android:orientation="vertical" > <cn.sunzn.tevent.TouchEventChilds android:id="@+id/childs" android:layout_width="200dp" android:layout_height="200dp" android:layout_gravity="center" android:background="#E1110D" android:text="@string/hello" /> </cn.sunzn.tevent.TouchEventFather>
package cn.sunzn.tevent; import android.app.Activity; import android.os.Bundle; import android.util.Log; import android.view.MotionEvent; public class TouchEventActivity extends Activity { public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); } public boolean dispatchTouchEvent(MotionEvent ev) { Log.e("sunzn", "TouchEventActivity | dispatchTouchEvent --> " + TouchEventUtil.getTouchAction(ev.getAction())); return super.dispatchTouchEvent(ev); } public boolean onTouchEvent(MotionEvent event) { Log.e("sunzn", "TouchEventActivity | onTouchEvent --> " + TouchEventUtil.getTouchAction(event.getAction())); return super.onTouchEvent(event); } }
package cn.sunzn.tevent; import android.content.Context; import android.util.AttributeSet; import android.util.Log; import android.view.MotionEvent; import android.widget.LinearLayout; public class TouchEventFather extends LinearLayout { public TouchEventFather(Context context) { super(context); } public TouchEventFather(Context context, AttributeSet attrs) { super(context, attrs); } public boolean dispatchTouchEvent(MotionEvent ev) { Log.e("sunzn", "TouchEventFather | dispatchTouchEvent --> " + TouchEventUtil.getTouchAction(ev.getAction())); return false; } public boolean onInterceptTouchEvent(MotionEvent ev) { Log.e("sunzn", "TouchEventFather | onInterceptTouchEvent --> " + TouchEventUtil.getTouchAction(ev.getAction())); return super.onInterceptTouchEvent(ev); } public boolean onTouchEvent(MotionEvent ev) { Log.e("sunzn", "TouchEventFather | onTouchEvent --> " + TouchEventUtil.getTouchAction(ev.getAction())); return super.onTouchEvent(ev); } }
package cn.sunzn.tevent; import android.content.Context; import android.util.AttributeSet; import android.util.Log; import android.view.MotionEvent; import android.widget.LinearLayout; public class TouchEventChilds extends LinearLayout { public TouchEventChilds(Context context) { super(context); } public TouchEventChilds(Context context, AttributeSet attrs) { super(context, attrs); } public boolean dispatchTouchEvent(MotionEvent ev) { Log.e("sunzn", "TouchEventChilds | dispatchTouchEvent --> " + TouchEventUtil.getTouchAction(ev.getAction())); return super.dispatchTouchEvent(ev); } public boolean onInterceptTouchEvent(MotionEvent ev) { Log.e("sunzn", "TouchEventChilds | onInterceptTouchEvent --> " + TouchEventUtil.getTouchAction(ev.getAction())); return super.onInterceptTouchEvent(ev); } public boolean onTouchEvent(MotionEvent ev) { Log.e("sunzn", "TouchEventChilds | onTouchEvent --> " + TouchEventUtil.getTouchAction(ev.getAction())); return super.onTouchEvent(ev); } }
package cn.sunzn.tevent; import android.view.MotionEvent; public class TouchEventUtil { public static String getTouchAction(int actionId) { String actionName = "Unknow:id=" + actionId; switch (actionId) { case MotionEvent.ACTION_DOWN: actionName = "ACTION_DOWN"; break; case MotionEvent.ACTION_MOVE: actionName = "ACTION_MOVE"; break; case MotionEvent.ACTION_UP: actionName = "ACTION_UP"; break; case MotionEvent.ACTION_CANCEL: actionName = "ACTION_CANCEL"; break; case MotionEvent.ACTION_OUTSIDE: actionName = "ACTION_OUTSIDE"; break; } return actionName; } }case1
拦截条件 | |||||||||
控件名称 | dispatchTouchEvent 返回值 | onInterceptTouchEvent 返回值 | onTouchEvent 返回值 | ||||||
TouchEventActivity | super.dispatchTouchEvent(ev) | --- | super.onTouchEvent(ev) | ||||||
TouchEventFather | false | super.onInterceptTouchEvent(ev) | super.onTouchEvent(ev) | ||||||
TouchEventChilds | super.dispatchTouchEvent(ev) | super.onInterceptTouchEvent(ev) | super.onTouchEvent(ev) | ||||||
运行结果 | |||||||||
Level | Time | PID | Application | Tag | Text | ||||
W | 05-10 03:41:19.743 | 414 | cn.sunzn.tevent | sunzn | TouchEventActivity | dispatchTouchEvent
--> ACTION_DOWN |
||||
E | 05-10 03:41:19.743 | 414 | cn.sunzn.tevent | sunzn | TouchEventFather | dispatchTouchEvent --> ACTION_DOWN | ||||
W | 05-10 03:41:19.743 | 414 | cn.sunzn.tevent | sunzn | TouchEventActivity | onTouchEvent --> ACTION_DOWN | ||||
W | 05-10 03:41:19.743 | 414 | cn.sunzn.tevent | sunzn | TouchEventActivity | dispatchTouchEvent --> ACTION_MOVE | ||||
W | 05-10 03:41:19.743 | 414 | cn.sunzn.tevent | sunzn | TouchEventActivity | onTouchEvent --> ACTION_MOVE | ||||
W | 05-10 03:41:19.743 | 414 | cn.sunzn.tevent | sunzn | TouchEventActivity | dispatchTouchEvent --> ACTION_UP | ||||
W | 05-10 03:41:19.743 | 414 | cn.sunzn.tevent | sunzn | TouchEventActivity | onTouchEvent --> ACTION_UP |
/**
* 代码运行后,事件首先由 TouchEventActivity 的 dispatchTouchEvent 方法分发给
* TouchEventFather 控件的dispatchTouchEvent,而该控件的 dispatchTouchEvent 返回
* false,表示对获取到的事件停止向下传递,同时也不对该事件进行消费。由于 TouchEventFather 获取的事件直接来自
* TouchEventActivity ,则会将事件返回给 TouchEventActivity 的 onTouchEvent 进行消费,最后直接由
* TouchEventActivity 来响应手指移动和抬起事件。
*/
case2
拦截条件 | |||||||||
控件名称 | dispatchTouchEvent 返回值 | onInterceptTouchEvent 返回值 | onTouchEvent 返回值 | ||||||
TouchEventActivity | super.dispatchTouchEvent(ev) | --- | super.onTouchEvent(ev) | ||||||
TouchEventFather | true | super.onInterceptTouchEvent(ev) | super.onTouchEvent(ev) | ||||||
TouchEventChilds | super.dispatchTouchEvent(ev) | super.onInterceptTouchEvent(ev) | super.onTouchEvent(ev) | ||||||
运行结果 | |||||||||
Level | Time | PID | Application | Tag | Text | ||||
W | 05-10 03:41:19.743 | 414 | cn.sunzn.tevent | sunzn | TouchEventActivity | dispatchTouchEvent --> ACTION_DOWN |
||||
E | 05-10 03:41:19.743 | 414 | cn.sunzn.tevent | sunzn | TouchEventFather | dispatchTouchEvent --> ACTION_DOWN | ||||
W | 05-10 03:41:19.743 | 414 | cn.sunzn.tevent | sunzn | TouchEventActivity | dispatchTouchEvent --> ACTION_MOVE | ||||
E | 05-10 03:41:19.743 | 414 | cn.sunzn.tevent | sunzn | TouchEventFather | dispatchTouchEvent --> ACTION_MOVE | ||||
W | 05-10 03:41:19.743 | 414 | cn.sunzn.tevent | sunzn | TouchEventActivity | dispatchTouchEvent --> ACTION_MOVE | ||||
E | 05-10 03:41:19.743 | 414 | cn.sunzn.tevent | sunzn | TouchEventFather | dispatchTouchEvent --> ACTION_MOVE | ||||
W | 05-10 03:41:19.743 | 414 | cn.sunzn.tevent | sunzn | TouchEventActivity | dispatchTouchEvent --> ACTION_MOVE | ||||
E | 05-10 03:41:19.743 | 414 | cn.sunzn.tevent | sunzn | TouchEventFather | dispatchTouchEvent --> ACTION_MOVE | ||||
W | 05-10 03:41:19.743 | 414 | cn.sunzn.tevent | sunzn | TouchEventActivity | dispatchTouchEvent --> ACTION_UP | ||||
E | 05-10 03:41:19.743 | 414 | cn.sunzn.tevent | sunzn | TouchEventFather | dispatchTouchEvent --> ACTION_UP | ||||
结果分析 | |||||||||
代码运行后,事件首先由 TouchEventActivity 的 dispatchTouchEvent 方法分发给 TouchEventFather 控件的dispatchTouchEvent,而该控件的 dispatchTouchEvent 返回 true,表示分发事件到TouchEventFather 控件并由该控件的dispatchTouchEvent 进行消费;TouchEventActivity 不断的分发事件到TouchEventFather 控件的dispatchTouchEvent,而TouchEventFather 控件的 dispatchTouchEvent 也不断的将获取到的事件进行消费。 |
case3
拦截条件 | |||||||||
控件名称 | dispatchTouchEvent 返回值 | onInterceptTouchEvent 返回值 | onTouchEvent 返回值 | ||||||
TouchEventActivity | super.dispatchTouchEvent(ev) | --- | super.onTouchEvent(ev) | ||||||
TouchEventFather | super.dispatchTouchEvent(ev) | true | super.onTouchEvent(ev) | ||||||
TouchEventChilds | super.dispatchTouchEvent(ev) | super.onInterceptTouchEvent(ev) | super.onTouchEvent(ev) | ||||||
运行结果 | |||||||||
Level | Time | PID | Application | Tag | Text | ||||
W | 05-10 05:34:46.333 | 481 | cn.sunzn.tevent | sunzn | TouchEventActivity | dispatchTouchEvent --> ACTION_DOWN | ||||
E | 05-10 05:34:46.333 | 481 | cn.sunzn.tevent | sunzn | TouchEventFather | dispatchTouchEvent --> ACTION_DOWN | ||||
I | 05-10 05:34:46.333 | 481 | cn.sunzn.tevent | sunzn | TouchEventFather | onInterceptTouchEvent --> ACTION_DOWN | ||||
D | 05-10 05:34:46.333 | 481 | cn.sunzn.tevent | sunzn | TouchEventFather | onTouchEvent --> ACTION_DOWN | ||||
W | 05-10 05:34:46.333 | 481 | cn.sunzn.tevent | sunzn | TouchEventActivity | onTouchEvent --> ACTION_DOWN | ||||
W | 05-10 05:34:46.343 | 481 | cn.sunzn.tevent | sunzn | TouchEventActivity | dispatchTouchEvent --> ACTION_MOVE | ||||
W | 05-10 05:34:46.343 | 481 | cn.sunzn.tevent | sunzn | TouchEventActivity | onTouchEvent --> ACTION_MOVE | ||||
W | 05-10 05:34:46.423 | 481 | cn.sunzn.tevent | sunzn | TouchEventActivity | dispatchTouchEvent --> ACTION_MOVE | ||||
W | 05-10 05:34:46.423 | 481 | cn.sunzn.tevent | sunzn | TouchEventActivity | onTouchEvent --> ACTION_MOVE | ||||
W | 05-10 05:34:46.433 | 481 | cn.sunzn.tevent | sunzn | TouchEventActivity | dispatchTouchEvent --> ACTION_MOVE | ||||
W | 05-10 05:34:46.433 | 481 | cn.sunzn.tevent | sunzn | TouchEventActivity | onTouchEvent --> ACTION_MOVE | ||||
W | 05-10 05:34:46.442 | 481 | cn.sunzn.tevent | sunzn | TouchEventActivity | dispatchTouchEvent --> ACTION_UP | ||||
W | 05-10 05:34:46.442 | 481 | cn.sunzn.tevent | sunzn | TouchEventActivity | onTouchEvent --> ACTION_UP | ||||
结果分析 | |||||||||
代码运行后,事件首先由 TouchEventActivity 的 dispatchTouchEvent 方法分发给 TouchEventFather 控件的 dispatchTouchEvent,而该控件的 dispatchTouchEvent 返回 super.dispatchTouchEvent(ev),表示对事件进行分发并向下传递给 TouchEventFather 控件的 onInterceptTouchEvent 方法,该方法返回 true 表示对所获取到的事件进行拦截并将事件传递给 TouchEventFather 控件的 onTouchEvent 进行处理,TouchEventFather 控件的 onTouchEvent 返回 super.onTouchEvent(ev)表示对事件没有做任何处理直接将事件返回给上级控件,由于 TouchEventFather 获取的事件直接来自 TouchEventActivity,所以 TouchEventFather 控件的 onTouchEvent 会将事件以冒泡方式直接返回给 TouchEventActivity 的 onTouchEvent 进行消费,后续的事件则会跳过 TouchEventFather 直接由 TouchEventActivity 的 onTouchEvent 消费来自 TouchEventActivity 自身分发的事件。 |
case4
控件名称 | dispatchTouchEvent 返回值 | onInterceptTouchEvent 返回值 | onTouchEvent 返回值 | ||||||
TouchEventActivity | super.dispatchTouchEvent(ev) | --- | super.onTouchEvent(ev) | ||||||
TouchEventFather | super.dispatchTouchEvent(ev) | false | super.onTouchEvent(ev) | ||||||
TouchEventChilds | super.dispatchTouchEvent(ev) | super.onInterceptTouchEvent(ev) | super.onTouchEvent(ev) | ||||||
运行结果 | |||||||||
Level | Time | PID | Application | Tag | Text | ||||
W | 05-10 06:31:47.565 | 512 | cn.sunzn.tevent | sunzn | TouchEventActivity | dispatchTouchEvent --> ACTION_DOWN | ||||
E | 05-10 06:31:47.565 | 512 | cn.sunzn.tevent | sunzn | TouchEventFather | dispatchTouchEvent --> ACTION_DOWN | ||||
I | 05-10 06:31:47.565 | 512 | cn.sunzn.tevent | sunzn | TouchEventFather | onInterceptTouchEvent --> ACTION_DOWN | ||||
E | 05-10 06:31:47.565 | 512 | cn.sunzn.tevent | sunzn | TouchEventChilds | dispatchTouchEvent --> ACTION_DOWN | ||||
I | 05-10 06:31:47.565 | 512 | cn.sunzn.tevent | sunzn | TouchEventChilds | onInterceptTouchEvent --> ACTION_DOWN | ||||
D | 05-10 06:31:47.565 | 512 | cn.sunzn.tevent | sunzn | TouchEventChilds | onTouchEvent --> ACTION_DOWN | ||||
D | 05-10 06:31:47.565 | 512 | cn.sunzn.tevent | sunzn | TouchEventFather | onTouchEvent --> ACTION_DOWN | ||||
W | 05-10 06:31:47.565 | 512 | cn.sunzn.tevent | sunzn | TouchEventActivity | onTouchEvent --> ACTION_DOWN | ||||
W | 05-10 06:31:47.652 | 512 | cn.sunzn.tevent | sunzn | TouchEventActivity | dispatchTouchEvent --> ACTION_MOVE | ||||
W | 05-10 06:31:47.652 | 512 | cn.sunzn.tevent | sunzn | TouchEventActivity | onTouchEvent --> ACTION_MOVE | ||||
W | 05-10 06:31:47.732 | 512 | cn.sunzn.tevent | sunzn | TouchEventActivity | dispatchTouchEvent --> ACTION_MOVE | ||||
W | 05-10 06:31:47.732 | 512 | cn.sunzn.tevent | sunzn | TouchEventActivity | onTouchEvent --> ACTION_MOVE | ||||
W | 05-10 06:31:47.812 | 512 | cn.sunzn.tevent | sunzn | TouchEventActivity | dispatchTouchEvent --> ACTION_MOVE | ||||
W | 05-10 06:31:47.812 | 512 | cn.sunzn.tevent | sunzn | TouchEventActivity | onTouchEvent --> ACTION_MOVE | ||||
W | 05-10 06:31:47.892 | 512 | cn.sunzn.tevent | sunzn | TouchEventActivity | dispatchTouchEvent --> ACTION_UP | ||||
W | 05-10 06:31:47.892 | 512 | cn.sunzn.tevent | sunzn | TouchEventActivity | onTouchEvent --> ACTION_UP | ||||
结果分析 | |||||||||
代码运行后,事件首先由 TouchEventActivity 的 dispatchTouchEvent 方法分发给 TouchEventFather 控件的 dispatchTouchEvent,而该控件的 dispatchTouchEvent 返回 super.dispatchTouchEvent(ev),表示对事件进行分发并向下传递给 TouchEventFather 控件的 onInterceptTouchEvent 方法,该方法返回 false 表示事件会被放行并传递到子控件 TouchEventChilds 的 dispatchTouchEvent 方法,同样 TouchEventChilds 的 dispatchTouchEvent 返回 super.dispatchTouchEvent(ev),表示对事件进行分发并向下传递给 TouchEventChilds 控件的 onInterceptTouchEvent 方法,TouchEventChilds 的 onInterceptTouchEvent 方法返回 super.onInterceptTouchEvent(ev) 默认会将事件传递给 TouchEventChilds 的 onTouchEvent 进行处理,TouchEventChilds 的 onTouchEvent 返回 super.onTouchEvent(ev) 表示对事件没有做任何处理直接将事件返回给上级控件,由于 TouchEventChilds 获取的事件直接来自 TouchEventFather,所以 TouchEventChilds 控件的 onTouchEvent 会将事件以冒泡方式直接返回给 TouchEventFather 的 onTouchEvent 进行消费,而 TouchEventFather 的 onTouchEvent 也返回了 super.onTouchEvent(ev),同样 TouchEventFather 的 onTouchEvent 也会将事件返回给上级控件,而 TouchEventFather 获取的事件直接来自 TouchEventActivity,所以 TouchEventFather 控件的 onTouchEvent 会将事件以冒泡方式直接返回给 TouchEventActivity 的 onTouchEvent 进行消费,后续的事件则会跳过 TouchEventFather 和 TouchEventChilds 直接由 TouchEventActivity 的 onTouchEvent 消费来自 TouchEventActivity 自身分发的事件。 |
case5
拦截条件 | |||||||||
控件名称 | dispatchTouchEvent 返回值 | onInterceptTouchEvent 返回值 | onTouchEvent 返回值 | ||||||
TouchEventActivity | super.dispatchTouchEvent(ev) | --- | super.onTouchEvent(ev) | ||||||
TouchEventFather | super.dispatchTouchEvent(ev) | false | super.onTouchEvent(ev) | ||||||
TouchEventChilds | true | super.onInterceptTouchEvent(ev) | super.onTouchEvent(ev) | ||||||
运行结果 | |||||||||
Level | Time | PID | Application | Tag | Text | ||||
W | 05-10 08:11:18.403 | 574 | cn.sunzn.tevent | sunzn | TouchEventActivity | dispatchTouchEvent --> ACTION_DOWN | ||||
E | 05-10 08:11:18.403 | 574 | cn.sunzn.tevent | sunzn | TouchEventFather | dispatchTouchEvent --> ACTION_DOWN | ||||
I | 05-10 08:11:18.403 | 574 | cn.sunzn.tevent | sunzn | TouchEventFather | onInterceptTouchEvent --> ACTION_DOWN | ||||
E | 05-10 08:11:18.403 | 574 | cn.sunzn.tevent | sunzn | TouchEventChilds | dispatchTouchEvent --> ACTION_DOWN | ||||
W | 05-10 08:11:19.652 | 574 | cn.sunzn.tevent | sunzn | TouchEventActivity | dispatchTouchEvent --> ACTION_MOVE | ||||
E | 05-10 08:11:19.652 | 574 | cn.sunzn.tevent | sunzn | TouchEventFather | dispatchTouchEvent --> ACTION_MOVE | ||||
I | 05-10 08:11:19.652 | 574 | cn.sunzn.tevent | sunzn | TouchEventFather | onInterceptTouchEvent --> ACTION_MOVE | ||||
E | 05-10 08:11:19.652 | 574 | cn.sunzn.tevent | sunzn | TouchEventChilds | dispatchTouchEvent --> ACTION_MOVE | ||||
W | 05-10 08:11:19.872 | 574 | cn.sunzn.tevent | sunzn | TouchEventActivity | dispatchTouchEvent --> ACTION_UP | ||||
E | 05-10 08:11:19.872 | 574 | cn.sunzn.tevent | sunzn | TouchEventFather | dispatchTouchEvent --> ACTION_UP | ||||
I | 05-10 08:11:19.872 | 574 | cn.sunzn.tevent | sunzn | TouchEventFather | onInterceptTouchEvent --> ACTION_UP | ||||
E | 05-10 08:11:19.872 | 574 | cn.sunzn.tevent | sunzn | TouchEventChilds | dispatchTouchEvent --> ACTION_UP | ||||
结果分析 | |||||||||
代码运行后,事件首先由 TouchEventActivity 的 dispatchTouchEvent 方法分发给 TouchEventFather 控件的 dispatchTouchEvent,该控件的 dispatchTouchEvent 返回super.dispatchTouchEvent(ev),事件会分发到 TouchEventFather 的 onInterceptTouchEvent,onInterceptTouchEvent 返回 false 表示放行当先事件;事件会被传递到子控件 TouchEventChilds 的 dispatchTouchEvent 方法,dispatchTouchEvent 返回 true 表示事件被分发到 TouchEventChilds 控件并由该控件的 dispatchTouchEvent 方法消费。后续的事件也会不断的重复上面的逻辑最终被 TouchEventChilds 的 dispatchTouchEvent 消费。 |
原文:http://blog.csdn.net/u013210620/article/details/48055549