本文主要通过先demo分析讲解
onTouchEvent,dispatchTouchEvent,onInterceptTouchEvent这三者在事件点击过程中的处理关系。
demo
分别自定义一个TextView(View),LinearLayout(ViewGroup)
自定义LinearLayout,并且复写以上三个方法,打印log
public class MyLinearLayout extends LinearLayout {
public MyLinearLayout(Context context) {
super(context);
}
public MyLinearLayout(Context context, AttributeSet attrs) {
super(context, attrs);
}
public MyLinearLayout(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
Log.d(MainActivity.TAG,"LinearLayout_onTouchEvent=" + getActions(event.getAction()));
return super.onTouchEvent(event);
}
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
Log.d(MainActivity.TAG,"LinearLayout_dispatchTouchEvent=" + getActions(ev.getAction()));
return super.dispatchTouchEvent(ev);
}
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
Log.d(MainActivity.TAG,"LinearLayout_onInterceptTouchEvent=" + getActions(ev.getAction()));
return super.onInterceptTouchEvent(ev);
}
private String getActions(int actionId) {
String action = null;
switch (actionId) {
case 0:
action = "ACTION_DOWN";
break;
case 1:
action = "ACTION_UP";
break;
case 2:
action = "ACTION_MOVE";
break;
}
return action;
}
}
自定义TextView,并且复写以上两个个方法(view没有onInterceptTouchEvent方法),打印log
public class MyTextView extends TextView {
public MyTextView(Context context) {
super(context);
}
public MyTextView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public MyTextView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
Log.d(MainActivity.TAG,"TextView_onTouchEvent=" + getActions(event.getAction()));
return super.onTouchEvent(event);
}
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
Log.d(MainActivity.TAG,"TextView_dispatchTouchEvent=" + getActions(ev.getAction()));
return super.dispatchTouchEvent(ev);
}
private String getActions(int actionId) {
String action = null;
switch (actionId) {
case 0:
action = "ACTION_DOWN";
break;
case 1:
action = "ACTION_UP";
break;
case 2:
action = "ACTION_MOVE";
break;
}
return action;
}
}
xml文件
<?xml version="1.0" encoding="utf-8"?>
<com.wpt.touch.MyLinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.wpt.touch.MyTextView
android:layout_width="match_parent"
android:layout_height="180dp"
android:background="#ff0000"
android:text="Hello World!" />
</com.wpt.touch.MyLinearLayout>
默认
两个自定义的复写方法都默认返回super….,然后运行点击TextView看看打印的log。
06-14 17:21:11.095 29470-29470/com.wpt.touch D/touchEvent: LinearLayout_dispatchTouchEvent=ACTION_DOWN
06-14 17:21:11.095 29470-29470/com.wpt.touch D/touchEvent: LinearLayout_onInterceptTouchEvent=ACTION_DOWN
06-14 17:21:11.095 29470-29470/com.wpt.touch D/touchEvent: TextView_dispatchTouchEvent=ACTION_DOWN
06-14 17:21:11.095 29470-29470/com.wpt.touch D/touchEvent: TextView_onTouchEvent=ACTION_DOWN
06-14 17:21:11.095 29470-29470/com.wpt.touch D/touchEvent: LinearLayout_onTouchEvent=ACTION_DOWN
通过log看到,默认情况的执行顺序是这样的,父dispatchTouchEvent→父onInterceptToutchEvent→子dispatchToutchEvent→子onTouchEvent→父onTouchEvent,如下图:
onTouchEvent
LinearLayout
现在把LinearLayout的onTouchEvent返回值改为true,看下打印的log情况:
06-15 10:58:26.465 15032-15032/com.wpt.touch D/touchEvent: LinearLayout_dispatchTouchEvent=ACTION_DOWN
06-15 10:58:26.465 15032-15032/com.wpt.touch D/touchEvent: LinearLayout_onInterceptTouchEvent=ACTION_DOWN
06-15 10:58:26.465 15032-15032/com.wpt.touch D/touchEvent: TextView_dispatchTouchEvent=ACTION_DOWN
06-15 10:58:26.465 15032-15032/com.wpt.touch D/touchEvent: TextView_onTouchEvent=ACTION_DOWN
06-15 10:58:26.465 15032-15032/com.wpt.touch D/touchEvent: LinearLayout_onTouchEvent=ACTION_DOWN
06-15 10:58:26.505 15032-15032/com.wpt.touch D/touchEvent: LinearLayout_dispatchTouchEvent=ACTION_MOVE
06-15 10:58:26.505 15032-15032/com.wpt.touch D/touchEvent: LinearLayout_onTouchEvent=ACTION_MOVE
06-15 10:58:26.525 15032-15032/com.wpt.touch D/touchEvent: LinearLayout_dispatchTouchEvent=ACTION_MOVE
06-15 10:58:26.525 15032-15032/com.wpt.touch D/touchEvent: LinearLayout_onTouchEvent=ACTION_MOVE
06-15 10:58:26.525 15032-15032/com.wpt.touch D/touchEvent: LinearLayout_dispatchTouchEvent=ACTION_UP
06-15 10:58:26.525 15032-15032/com.wpt.touch D/touchEvent: LinearLayout_onTouchEvent=ACTION_UP
我们看到打印的log比之前的多了很多,LinearLayout不仅处理了DOWN事件,也处理的MOVE,UP事件,三个方法的执行顺序还是跟上面默认的一致。如图:
TextView
接下来我们把TextView的onTouchEvent返回值改为true试试:
06-15 11:05:11.435 20075-20075/com.wpt.touch D/touchEvent: LinearLayout_dispatchTouchEvent=ACTION_DOWN
06-15 11:05:11.435 20075-20075/com.wpt.touch D/touchEvent: LinearLayout_onInterceptTouchEvent=ACTION_DOWN
06-15 11:05:11.435 20075-20075/com.wpt.touch D/touchEvent: TextView_dispatchTouchEvent=ACTION_DOWN
06-15 11:05:11.435 20075-20075/com.wpt.touch D/touchEvent: TextView_onTouchEvent=ACTION_DOWN
06-15 11:05:11.495 20075-20075/com.wpt.touch D/touchEvent: LinearLayout_dispatchTouchEvent=ACTION_MOVE
06-15 11:05:11.495 20075-20075/com.wpt.touch D/touchEvent: LinearLayout_onInterceptTouchEvent=ACTION_MOVE
06-15 11:05:11.495 20075-20075/com.wpt.touch D/touchEvent: TextView_dispatchTouchEvent=ACTION_MOVE
06-15 11:05:11.495 20075-20075/com.wpt.touch D/touchEvent: TextView_onTouchEvent=ACTION_MOVE
06-15 11:05:11.495 20075-20075/com.wpt.touch D/touchEvent: LinearLayout_dispatchTouchEvent=ACTION_UP
06-15 11:05:11.495 20075-20075/com.wpt.touch D/touchEvent: LinearLayout_onInterceptTouchEvent=ACTION_UP
06-15 11:05:11.495 20075-20075/com.wpt.touch D/touchEvent: TextView_dispatchTouchEvent=ACTION_UP
06-15 11:05:11.495 20075-20075/com.wpt.touch D/touchEvent: TextView_onTouchEvent=ACTION_UP
我们看到打印的log,LinearLayout,TextView不仅处理了DOWN事件,也处理的MOVE,UP事件,唯一不同的一点是LinearLayout不执行onTouchEvent方法了,三个方法的执行顺序是:
父dispatchTouchEvent→父onInterceptToutchEvent→子dispatchToutchEvent
→子onTouchEvent→父onTouchEvent 如图:
因为TextView的onTouchEvent返回true,说明它消费了该方法,所以LinearLayout的onTouchEvent就不会再执行了。
dispatchTouchEvent
LinearLayout
现在我们把LinearLayout的dispatchTouchEvent返回true看下log:
06-15 11:29:16.985 6097-6097/com.wpt.touch D/touchEvent: LinearLayout_dispatchTouchEvent=ACTION_DOWN
06-15 11:29:17.035 6097-6097/com.wpt.touch D/touchEvent: LinearLayout_dispatchTouchEvent=ACTION_MOVE
06-15 11:29:17.035 6097-6097/com.wpt.touch D/touchEvent: LinearLayout_dispatchTouchEvent=ACTION_MOVE
06-15 11:29:17.035 6097-6097/com.wpt.touch D/touchEvent: LinearLayout_dispatchTouchEvent=ACTION_UP
发现只执行了LinearLayout的一个方法,而且没有执行TextView的相关方法,如图:
因为LinearLayout在dispatchTouchEvent返回true,表明消费了该事件,就不会往下传递了。
TextView
现在我们把TextView的dispatchTouchEvent返回true看下log:
06-15 14:36:33.342 13228-13228/com.wpt.touch D/touchEvent: LinearLayout_dispatchTouchEvent=ACTION_DOWN
06-15 14:36:33.342 13228-13228/com.wpt.touch D/touchEvent: LinearLayout_onInterceptTouchEvent=ACTION_DOWN
06-15 14:36:33.342 13228-13228/com.wpt.touch D/touchEvent: TextView_dispatchTouchEvent=ACTION_DOWN
06-15 14:36:33.352 13228-13228/com.wpt.touch D/touchEvent: LinearLayout_dispatchTouchEvent=ACTION_MOVE
06-15 14:36:33.352 13228-13228/com.wpt.touch D/touchEvent: LinearLayout_onInterceptTouchEvent=ACTION_MOVE
06-15 14:36:33.352 13228-13228/com.wpt.touch D/touchEvent: TextView_dispatchTouchEvent=ACTION_MOVE
06-15 14:36:33.372 13228-13228/com.wpt.touch D/touchEvent: LinearLayout_dispatchTouchEvent=ACTION_MOVE
06-15 14:36:33.372 13228-13228/com.wpt.touch D/touchEvent: LinearLayout_onInterceptTouchEvent=ACTION_MOVE
06-15 14:36:33.372 13228-13228/com.wpt.touch D/touchEvent: TextView_dispatchTouchEvent=ACTION_MOVE
06-15 14:36:33.382 13228-13228/com.wpt.touch D/touchEvent: LinearLayout_dispatchTouchEvent=ACTION_MOVE
06-15 14:36:33.382 13228-13228/com.wpt.touch D/touchEvent: LinearLayout_onInterceptTouchEvent=ACTION_MOVE
06-15 14:36:33.382 13228-13228/com.wpt.touch D/touchEvent: TextView_dispatchTouchEvent=ACTION_MOVE
06-15 14:36:33.392 13228-13228/com.wpt.touch D/touchEvent: LinearLayout_dispatchTouchEvent=ACTION_MOVE
06-15 14:36:33.392 13228-13228/com.wpt.touch D/touchEvent: LinearLayout_onInterceptTouchEvent=ACTION_MOVE
06-15 14:36:33.392 13228-13228/com.wpt.touch D/touchEvent: TextView_dispatchTouchEvent=ACTION_MOVE
06-15 14:36:33.392 13228-13228/com.wpt.touch D/touchEvent: LinearLayout_dispatchTouchEvent=ACTION_UP
06-15 14:36:33.392 13228-13228/com.wpt.touch D/touchEvent: LinearLayout_onInterceptTouchEvent=ACTION_UP
06-15 14:36:33.392 13228-13228/com.wpt.touch D/touchEvent: TextView_dispatchTouchEvent=ACTION_UP
可以看到LinearLayout与TextView都只执行了dispatchTouchEvent方法,执行顺序如图:
因为TextView在dispatchTouchEvent返回true,表明消费了该事件,就不会往下传递了,并且直接处理Move,UP等事件。
onInterceptTouchEvent
接下来我们把LinearLayout的onTouchEvent返回值改为true看看log:
06-15 14:46:19.872 23006-23006/com.wpt.touch D/touchEvent: LinearLayout_dispatchTouchEvent=ACTION_DOWN
06-15 14:46:19.872 23006-23006/com.wpt.touch D/touchEvent: LinearLayout_onInterceptTouchEvent=ACTION_DOWN
06-15 14:46:19.872 23006-23006/com.wpt.touch D/touchEvent: LinearLayout_onTouchEvent=ACTION_DOWN
发现不会往TextView传递了,执行顺序如图:
总结
好了,到此,从该demo分析以上三个方法修改返回值的各个执行情况,下次从源码角度去分析这三个方法。