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