**
一、当一个按钮的点击事件产生后,它的传递过程如下:Activity–>Window–>View
**
1、点击事件用MotionEvent来表示,当一个点击事件发生时事件最先传递给当前的Activity,由Activity的dispatchTouchEvent来进行事件的分发。
2、在Activity的dispatchTouchEvent中通过window对象(通过getwindow获得)将事件传递给当前窗口的顶层view,即DecorView
3、DecorView通过getWindow().getDecorView().findViewById(android.R.id.content))来获得,我们通过setContentView所设置的就是decorview的子ViewGroup。
4、DecorView通过superDispatchTouchEvent传递给顶层view,就是我们通过setContentView设置的viewgroup
5、viewgroup通过自己的dispatchTouchEvent继续进行事件的传递……
Activity的dispatchTouchEvent方法,调用window对象的superDispatchTouchEvent方法
public boolean dispatchTouchEvent(MotionEvent ev) {
if (ev.getAction() == MotionEvent.ACTION_DOWN) {
onUserInteraction();
}
if (getWindow().superDispatchTouchEvent(ev)) {
return true;
}
return onTouchEvent(ev);
}
PhoneWindow的superDispatchTouchEvent方法,调用DecorView的superDispatchTouchEvent方法
@Override
public boolean superDispatchTouchEvent(MotionEvent event) {
return mDecor.superDispatchTouchEvent(event);
}
DecorView的superDispatchTouchEvent方法,调用super.dispatchTouchEvent方法,因为DecorView继承FrameLayout,所以super.dispatchTouchEven进入ViewGroup的dispatchTouchEvent方法,进而把事件从根viewgroup向下传递。
public boolean superDispatchTouchEvent(MotionEvent event) {
return super.dispatchTouchEvent(event);
}
**
二、事件从根Viewgroup向下传递的过程
**
1、主要是有三个方法来进行传递和处理的
(1)、public boolean dispatchTouchEvent(MotionEvent event)
// 事件分发,activity把事件传递给了viewgroup,viewgroup的dispatchTouchEvent方法会被调用,viewgroup把事件传递给了view,view的dispatchTouchEvent方法会被调用。
(2)、public boolean dispatchTouchEvent(MotionEvent event)
// 事件拦截,只有viewgroup有,view没有,如果事件被拦截了,就不会再向下传递了。
// 返回false表示不做拦截,事件将向下分发到子View的dispatchTouchEvent方法。
(3)、public boolean onTouchEvent(MotionEvent ev)
// 返回true表示事件被消费,本次的事件终止。返回false表示事件没有被消费,将调用父View的onTouchEvent方法
注:ViewGroup有onInterceptTouchEvent方法,view没有
三个方法的关系看这里
2、伪代码表示
public boolean dispatchTouchEvent(MotionEvent ev) {
boolean consume = false; //事件是否被消费
if (onInterceptTouchEvent(ev)){ //调用onInterceptTouchEvent判断是否拦截事件
consume = onTouchEvent(ev); //如果拦截则调用自身的onTouchEvent方法
}else{
consume = child.dispatchTouchEvent(ev); //不拦截调用子View的dispatchTouchEvent方法
}
return consume;//返回值表示事件是否被消费true事件终止,false调用父View的onTouchEvent方法
}
3、图示表示