Android onTouchEvent,dispatchTouchEvent,onInterceptTouchEvent分析

本文主要通过先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分析以上三个方法修改返回值的各个执行情况,下次从源码角度去分析这三个方法。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值