Android中的view是树形结构,可以进行有序分发,最先接收到的是activity,传递顺序:
Activity -> PhoneWindow -> DecorView -> ViewGroup -> … -> View
其中 activty ,viewGroup ,view 的包含的方法:先用一张图片显示(√表示含有改方法,x没有改方法)
本片主要是讲解activity中的事件分发:
public boolean dispatchTouchEvent(MotionEvent ev) {
if (ev.getAction() == MotionEvent.ACTION_DOWN) {
onUserInteraction();//分析1
}
if (getWindow().superDispatchTouchEvent(ev)) {//分析2
return true;
}
return onTouchEvent(ev);//分析3
}
1.onUserInteraction();这个方法为空方法
作用:当此activity在栈顶时,触屏点击按home,back,menu键等都会触发此方法
2.getWindow().superDispatchTouchEvent(ev); 这个方法是个抽象方法。
//此处的getWindow()---> :
public Window getWindow() {
return mWindow;
}
//这个mWindow应用对应对象是-->
mWindow = new PhoneWindow(this, window, activityConfigCallback);
//可以发现这个mWindow的是指向的PhoneWindow,PhoneWindow是window的子类;
//调用的getWindow().superDispatchTouchEvent(ev)这个方法是:
@Override
public boolean superDispatchTouchEvent(MotionEvent event) {
return mDecor.superDispatchTouchEvent(event);
}
//而mDecor.superDispatchTouchEvent(event)方法是:
public boolean superDispatchTouchEvent(MotionEvent event) {
return super.dispatchTouchEvent(event);
// 调用父类的方法 = ViewGroup的dispatchTouchEvent()
}
/*
解释一下:
DecorView类是PhoneWindow类的一个内部类
DecorView继承自FrameLayout,是所有界面的父类
FrameLayout是ViewGroup的子类,故DecorView的间接父类 = ViewGroup
*/
//因此这个方法其实最终调用的是viewGroup的dispatchTouchEvent();
3.onTouchEvent(ev);分析
public boolean onTouchEvent(MotionEvent event) {
if (mWindow.shouldCloseOnTouch(this, event)) {
finish();
return true;
}
return false;
}
//其中mWindow.shouldCloseOnTouch(this, event)这个方法是触摸事件没有被下面的任何View接受,触摸到边界的情况。
//返回true:说明事件在边界外,即 消费事件
// 返回false:未消费(默认)
最后总结一下:
activity的点击事件
——> activity的 dispatchTouchEvent()
——> 通过调用 getWindow().superDispatchTouchEvent(ev) 的当方法
——>(1) 得到viewGroup的 dispatchTouchEvent() 的返回值,返回ture时,activity.dispatchTouchEvent()就会 返会 ture,事件分发结束;
(2) 当viewGroup的 dispatchTouchEvent() 的返回值,返回false时,调用 activity.onTouchEvent() 得到返回值(无论返回什么,事件分发都结束):事件在边界范围内返回false。
参考资料:作者Carson_Ho 的 https://www.jianshu.com/p/38015afcdb58