Android onTouchEvent,dispatchTouchEvent,onInterceptTouchEvent分析

来源:互联网 发布:智慧课堂软件 编辑:程序博客网 时间:2024/05/18 03:08

本文主要通过先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_DOWN06-14 17:21:11.095 29470-29470/com.wpt.touch D/touchEvent: LinearLayout_onInterceptTouchEvent=ACTION_DOWN06-14 17:21:11.095 29470-29470/com.wpt.touch D/touchEvent: TextView_dispatchTouchEvent=ACTION_DOWN06-14 17:21:11.095 29470-29470/com.wpt.touch D/touchEvent: TextView_onTouchEvent=ACTION_DOWN06-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_DOWN06-15 10:58:26.465 15032-15032/com.wpt.touch D/touchEvent: LinearLayout_onInterceptTouchEvent=ACTION_DOWN06-15 10:58:26.465 15032-15032/com.wpt.touch D/touchEvent: TextView_dispatchTouchEvent=ACTION_DOWN06-15 10:58:26.465 15032-15032/com.wpt.touch D/touchEvent: TextView_onTouchEvent=ACTION_DOWN06-15 10:58:26.465 15032-15032/com.wpt.touch D/touchEvent: LinearLayout_onTouchEvent=ACTION_DOWN06-15 10:58:26.505 15032-15032/com.wpt.touch D/touchEvent: LinearLayout_dispatchTouchEvent=ACTION_MOVE06-15 10:58:26.505 15032-15032/com.wpt.touch D/touchEvent: LinearLayout_onTouchEvent=ACTION_MOVE06-15 10:58:26.525 15032-15032/com.wpt.touch D/touchEvent: LinearLayout_dispatchTouchEvent=ACTION_MOVE06-15 10:58:26.525 15032-15032/com.wpt.touch D/touchEvent: LinearLayout_onTouchEvent=ACTION_MOVE06-15 10:58:26.525 15032-15032/com.wpt.touch D/touchEvent: LinearLayout_dispatchTouchEvent=ACTION_UP06-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_DOWN06-15 11:05:11.435 20075-20075/com.wpt.touch D/touchEvent: LinearLayout_onInterceptTouchEvent=ACTION_DOWN06-15 11:05:11.435 20075-20075/com.wpt.touch D/touchEvent: TextView_dispatchTouchEvent=ACTION_DOWN06-15 11:05:11.435 20075-20075/com.wpt.touch D/touchEvent: TextView_onTouchEvent=ACTION_DOWN06-15 11:05:11.495 20075-20075/com.wpt.touch D/touchEvent: LinearLayout_dispatchTouchEvent=ACTION_MOVE06-15 11:05:11.495 20075-20075/com.wpt.touch D/touchEvent: LinearLayout_onInterceptTouchEvent=ACTION_MOVE06-15 11:05:11.495 20075-20075/com.wpt.touch D/touchEvent: TextView_dispatchTouchEvent=ACTION_MOVE06-15 11:05:11.495 20075-20075/com.wpt.touch D/touchEvent: TextView_onTouchEvent=ACTION_MOVE06-15 11:05:11.495 20075-20075/com.wpt.touch D/touchEvent: LinearLayout_dispatchTouchEvent=ACTION_UP06-15 11:05:11.495 20075-20075/com.wpt.touch D/touchEvent: LinearLayout_onInterceptTouchEvent=ACTION_UP06-15 11:05:11.495 20075-20075/com.wpt.touch D/touchEvent: TextView_dispatchTouchEvent=ACTION_UP06-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_DOWN06-15 11:29:17.035 6097-6097/com.wpt.touch D/touchEvent: LinearLayout_dispatchTouchEvent=ACTION_MOVE06-15 11:29:17.035 6097-6097/com.wpt.touch D/touchEvent: LinearLayout_dispatchTouchEvent=ACTION_MOVE06-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_DOWN06-15 14:36:33.342 13228-13228/com.wpt.touch D/touchEvent: LinearLayout_onInterceptTouchEvent=ACTION_DOWN06-15 14:36:33.342 13228-13228/com.wpt.touch D/touchEvent: TextView_dispatchTouchEvent=ACTION_DOWN06-15 14:36:33.352 13228-13228/com.wpt.touch D/touchEvent: LinearLayout_dispatchTouchEvent=ACTION_MOVE06-15 14:36:33.352 13228-13228/com.wpt.touch D/touchEvent: LinearLayout_onInterceptTouchEvent=ACTION_MOVE06-15 14:36:33.352 13228-13228/com.wpt.touch D/touchEvent: TextView_dispatchTouchEvent=ACTION_MOVE06-15 14:36:33.372 13228-13228/com.wpt.touch D/touchEvent: LinearLayout_dispatchTouchEvent=ACTION_MOVE06-15 14:36:33.372 13228-13228/com.wpt.touch D/touchEvent: LinearLayout_onInterceptTouchEvent=ACTION_MOVE06-15 14:36:33.372 13228-13228/com.wpt.touch D/touchEvent: TextView_dispatchTouchEvent=ACTION_MOVE06-15 14:36:33.382 13228-13228/com.wpt.touch D/touchEvent: LinearLayout_dispatchTouchEvent=ACTION_MOVE06-15 14:36:33.382 13228-13228/com.wpt.touch D/touchEvent: LinearLayout_onInterceptTouchEvent=ACTION_MOVE06-15 14:36:33.382 13228-13228/com.wpt.touch D/touchEvent: TextView_dispatchTouchEvent=ACTION_MOVE06-15 14:36:33.392 13228-13228/com.wpt.touch D/touchEvent: LinearLayout_dispatchTouchEvent=ACTION_MOVE06-15 14:36:33.392 13228-13228/com.wpt.touch D/touchEvent: LinearLayout_onInterceptTouchEvent=ACTION_MOVE06-15 14:36:33.392 13228-13228/com.wpt.touch D/touchEvent: TextView_dispatchTouchEvent=ACTION_MOVE06-15 14:36:33.392 13228-13228/com.wpt.touch D/touchEvent: LinearLayout_dispatchTouchEvent=ACTION_UP06-15 14:36:33.392 13228-13228/com.wpt.touch D/touchEvent: LinearLayout_onInterceptTouchEvent=ACTION_UP06-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_DOWN06-15 14:46:19.872 23006-23006/com.wpt.touch D/touchEvent: LinearLayout_onInterceptTouchEvent=ACTION_DOWN06-15 14:46:19.872 23006-23006/com.wpt.touch D/touchEvent: LinearLayout_onTouchEvent=ACTION_DOWN

发现不会往TextView传递了,执行顺序如图:
这里写图片描述

总结

好了,到此,从该demo分析以上三个方法修改返回值的各个执行情况,下次从源码角度去分析这三个方法。

阅读全文
0 0
原创粉丝点击