
首先先判断当前事件是否是Down事件,如果是就调用onUserInteraction方法,如果不是就不会调用,所以Up,Move方法不会调用该方法。
public boolean dispatchTouchEvent(MotionEvent ev) {
if (ev.getAction() == MotionEvent.ACTION_DOWN) {
onUserInteraction();
}
if (getWindow().superDispatchTouchEvent(ev)) {
return true;
}
return onTouchEvent(ev);
}Activity的attach源码:
final void attach(Context context, ActivityThread aThread,
Instrumentation instr, ....){
.......
mWindow = new PhoneWindow(this, window, activityConfigCallback);
......
}
public Window getWindow() {
return mWindow;
}从这里看出getWindow返回的是一个PhoneWindow对象,
public class PhoneWindow extends Window implements MenuBuilder.Callback
并且PhoneWindow对象继承自Window,由于PhoneWindow类实现了Window的抽象方法superDispatchTouchEvent
@Override
public boolean superDispatchTouchEvent(MotionEvent event) {
return mDecor.superDispatchTouchEvent(event);
}这里mDecor为DecorView对象,通过查看DecorView类的
public boolean superDispatchTouchEvent(MotionEvent event) {
return super.dispatchTouchEvent(event);
}由于DecorView继承自FragmentLayout
public class DecorView extends FrameLayout
而FragmentLayout又继承自viewGroup
public class FrameLayout extends ViewGroup
所以调用的就是viewgroup的dispatchTouchEvent方法
综上:
Activity的getWindow().superDispatchTouchEvent(ev)就是调用的Viewgroup dispatchTouchEvent方法
Window:是一个抽象基类,作用于外观用户界面和行为策略表示一个窗口,它包含一个View tree和窗口的layout 参数。View tree的root View可以通过getDecorView得到。还可以设置Window的Content View。其实现类是PhoneWindow。Activity,Dialog,Toast,都包含一个Window,该Window在Activity的attach()函数中mWindow = new PhoneWindow(this)创建。DecorView:该类是PhoneWindow类的内部类,继承自FrameLayout,它是所有应用窗口的根View,PhoneWindow设置DecorView为应用窗口的根视图。PhoneWindow:PhoneWindow对象帮我们创建了一个PhoneWindow内部类DecorView(父类为FrameLayout)窗口顶层视图Activity的dispatchTouchEvent方法开始onUserInceration方法FragmentLayout,也就是ViewGroup将事件分发给子view,接着调用Activity的setContentView方法加载viewActivity下的子view拦截事件,就不会调用Activity的onTouchEvent方法;当viewgroup的dispatchTouchEvent方法返回true就直接返回,也不会调用Activity的onTouchEvent方法;当子view没有处理事件就交给viewgroup处理,如果还没有处理事件,一直向上传递,最后交给Activity来消费该事件public void onUserInteraction() {}
空实现方法,简单解释:
Key,Touch,Trackball事件分发到当前Activity就会被调用。如果想让Activity在运行的时候,能够得知用户正在与设备交互,就可以override该方法。onUserLeaveHint是为了帮助Activities智能的管理状态栏Notification;特别是为了帮助Activities在恰当的时间取消Notification,就是管理通知public boolean onTouchEvent(MotionEvent event) {
//如果Activity下的view没有处理该事件,就会交给Activity来消费该事件
if (mWindow.shouldCloseOnTouch(this, event)) {
finish();
return true;
}
return false;
}
public boolean shouldCloseOnTouch(Context context, MotionEvent event) {
///判断mCloseOnTouchOutside标记及是否为ACTION_DOWN事件,同时判断event的x、y坐标是不是超出Bounds,然后检查FrameLayout的content的id的DecorView是否为空
final boolean isOutside =
event.getAction() == MotionEvent.ACTION_DOWN && isOutOfBounds(context, event)
|| event.getAction() == MotionEvent.ACTION_OUTSIDE;
if (mCloseOnTouchOutside && peekDecorView() != null && isOutside) {
return true;
}
return false;
}