首页 > 代码库 > Android中dispatchTouchEvent、onInterceptTouchEvent和onTouchEvent事件分析

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:消费。

Android中dispatchTouchEvent、onInterceptTouchEvent和onTouchEvent事件分析