Android中dispatchTouchEvent、onInterceptTouchEvent和onTouchEvent事件分析

因为触摸事件一定会触发的ACTION是DOWN,这个也是最先触发的,所以标题中的三个方法研究的也就是这个DOWN事件的传递情况。

下面直接贴出测试代码,边看边讲:

一个Activity,Activity中只有dispatchTouchEvent和onTouchEvent方法。

public class MainActivity extends Activity
{
    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }

    @Override
    public boolean dispatchTouchEvent(MotionEvent ev)
    {
        // TODO Auto-generated method stub
        System.out.println(getClass().getSimpleName() + " dispatchTouchEvent");
        return super.dispatchTouchEvent(ev);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event)
    {
        // TODO Auto-generated method stub
        System.out.println(getClass().getSimpleName() + " onTouchEvent");
        return super.onTouchEvent(event);
    }
}

三个自定义的控件,前两个是ViewGroup类型,后一个是view类型。

ViewGroup有dispatchTouchEvent,onInterceptTouchEvent和onTouchEvent方法。

public class MyLinearLayout1 extends LinearLayout
{
    public MyLinearLayout1(Context context)
    {
        super(context);
        // TODO Auto-generated constructor stub
    }

    public MyLinearLayout1(Context context, AttributeSet attrs, int defStyle)
    {
        super(context, attrs, defStyle);
        // TODO Auto-generated constructor stub
    }

    public MyLinearLayout1(Context context, AttributeSet attrs)
    {
        super(context, attrs);
        // TODO Auto-generated constructor stub
    }

    @Override
    public boolean dispatchTouchEvent(MotionEvent ev)
    {
        // TODO Auto-generated method stub
        System.out.println(getClass().getSimpleName() + " dispatchTouchEvent");
        return super.dispatchTouchEvent(ev);
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev)
    {
        // TODO Auto-generated method stub
        System.out.println(getClass().getSimpleName() + " onInterceptTouchEvent");
        return super.onInterceptTouchEvent(ev);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event)
    {
        // TODO Auto-generated method stub
        System.out.println(getClass().getSimpleName() + " onTouchEvent");
        return super.onTouchEvent(event);
    }
}
public class MyLinearLayout2 extends LinearLayout
{
    public MyLinearLayout2(Context context)
    {
        super(context);
        // TODO Auto-generated constructor stub
    }

    public MyLinearLayout2(Context context, AttributeSet attrs, int defStyle)
    {
        super(context, attrs, defStyle);
        // TODO Auto-generated constructor stub
    }

    public MyLinearLayout2(Context context, AttributeSet attrs)
    {
        super(context, attrs);
        // TODO Auto-generated constructor stub
    }

    @Override
    public boolean dispatchTouchEvent(MotionEvent ev)
    {
        // TODO Auto-generated method stub
        System.out.println(getClass().getSimpleName() + " dispatchTouchEvent");
        return super.dispatchTouchEvent(ev);
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev)
    {
        // TODO Auto-generated method stub
        System.out.println(getClass().getSimpleName() + " onInterceptTouchEvent");
        return true;
    }

    @Override
    public boolean onTouchEvent(MotionEvent event)
    {
        // TODO Auto-generated method stub
        System.out.println(getClass().getSimpleName() + " onTouchEvent");
        return true;
    }
}
public class MyTextView extends TextView
{
    public MyTextView(Context context)
    {
        super(context);
        // TODO Auto-generated constructor stub
    }

    public MyTextView(Context context, AttributeSet attrs, int defStyle)
    {
        super(context, attrs, defStyle);
        // TODO Auto-generated constructor stub
    }

    public MyTextView(Context context, AttributeSet attrs)
    {
        super(context, attrs);
        // TODO Auto-generated constructor stub
    }

    @Override
    public boolean dispatchTouchEvent(MotionEvent event)
    {
        // TODO Auto-generated method stub
        System.out.println(getClass().getSimpleName() + " dispatchTouchEvent");
        return super.dispatchTouchEvent(event);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event)
    {
        // TODO Auto-generated method stub
        System.out.println(getClass().getSimpleName() + " onTouchEvent");
        return super.onTouchEvent(event);
    }
}
<com.testtouchevent.MyLinearLayout1 xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center"
    android:orientation="vertical" >

    <com.testtouchevent.MyLinearLayout2
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:background="@android:color/darker_gray"
        android:orientation="vertical"
        android:padding="20dp" >

        <com.testtouchevent.MyTextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:background="@android:color/white"
            android:gravity="center"
            android:padding="20dp"
            android:text="me is textview" />
    </com.testtouchevent.MyLinearLayout2>

</com.testtouchevent.MyLinearLayout1>

以上代码中各控件的相关方法执行顺序是这样的:

MainActivity                MyLinearLayout1                                             MyLinearLayout2                                            MyTextView

dispatchTouchEvent->dispatchTouchEvent->onInterceptTouchEvent->dispatchTouchEvent->onInterceptTouchEvent->dispatchTouchEvent

onTouchEvent<-        onTouchEvent<-                                                     onTouchEvent<-                                    onTouchEvent

dispatchTouchEvent:决定了事件是否继续分发下去和是否响应事件,false:继续分发,true:不继续分发,此次事件到此结束,也不会有任何控件执行onTouchEvent方法。

onInterceptTouchEvent:决定了是否拦截该事件,false:不拦截,true:拦截,此时当前控件执行onTouchEvent方法。

onTouchEvent:决定了是否消费该事件,false:不消费,true:消费。

原文地址:https://www.cnblogs.com/yushilong/p/4059401.html