前言
我们都知道给一个控件注册点击事件是只需要setOnClickListener,传入一个实现了onClick方法的匿名内部类,注册触摸事件只需要setOnTouchListener,传入一个实现了onTouch方法的匿名内部类,但是你会发现onTouch不同于onClick的一点是它是具有返回值的,这个返回值有什么用呢,onTouch和onClick方法谁先被调用呢?他们都是在那个函数中被调用的呢?下面我们就来看一看!
基础
//
button.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View view, MotionEvent motionEvent) {
System.out.println("onTouch");
return false;
}
});
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
System.out.println("onClick");
}
});
//
09:37:30.432 6758-6758/com.example.administrator.mydemo I/System.out: onTouch
09:37:30.538 6758-6758/com.example.administrator.mydemo I/System.out: onTouch
09:37:30.541 6758-6758/com.example.administrator.mydemo I/System.out: onTouch
09:37:30.548 6758-6758/com.example.administrator.mydemo I/System.out: onClick
我们可以看到onTouch是先于onClick被调
用的,那么我们在手都抛一个异常来看一下他的函数调用栈
//
at com.example.administrator.mydemo.MainActivity$1.onTouch(MainActivity.java:29)
at android.view.View.dispatchTouchEvent(View.java:11730)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2963)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2593)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2963)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2593)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2963)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2593)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2963)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2593)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2963)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2593)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2963)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2593)
at com.android.internal.policy.DecorView.superDispatchTouchEvent(DecorView.java:448)
at com.android.internal.policy.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1828)
at android.app.Activity.dispatchTouchEvent(Activity.java:3360)
//
这个只是截取了一部分,我们只看到追溯到Activity即可,所以对于onTouch方法,它是这样被调用的 … … -> Activity.dispatchTouchEvent -> PhoneWindow.superDispatchTouchEvent -> DecorView.superDisparchTouchEvent -> ViewGroup.dispatchTouchEvent – > ViewGroup.dispatchTransformedTouchEvent -> View.dispatchTouchEvent 那我们就可以按照这个顺序来看一看正常情况下的事件流的流向和相关函数代码
同时我们也可以看出对Touch事件它是由Activty->ViewGroup->View三层结构由外到内,Android5.0后代码变得更复杂了,但是原理没有变,我们就看一看便于理解的老代码
在开始之前为了第一次接触的人便于理解,我就简单的把情况设置为这个Activity中只有一个Layout,Layout中只有一个Button,所以只有一个Activty,一个ViewGroup,一个View,但是你要明白的是在安卓里ViewGroup也是一个View,View拥有dispatch方法,而ViewGroup作为它的子类重写了该方法,在后面提到时你要区分它调用的是作为Layout(ViewGroup)的dispatch方法,还是Layout作为一个View的dispatch方法!!!另外你还要区分ViewGroup是View的子类,Button是ViewGroup的子view
继续阅读 →