本文适用于对Android事件分发机制有一定基础的开发者阅读,主要是通过对Activity类中的事件分发、事件消费的源代码进行解析以达到完全理解其原理的目的

  • (一)Android事件分发机制 - View篇
  • (二)Android事件分发机制 - ViewGroup篇
  • (三)Android事件分发机制 - Activity篇
  • (四)Android事件分发机制 - 总结篇

当一个点击操作发生时,事件最先传递给当前的Activity,由ActivitydispatchTouchEvent来进行事件的分发,接下来我们通过源代码(基于Android6.0)看看这个方法内部到底做了哪些事情。

1、Activity#dispatchTouchEvent源码解析

public boolean dispatchTouchEvent(MotionEvent ev) {    if (ev.getAction() == MotionEvent.ACTION_DOWN) {        onUserInteraction();    }    if (getWindow().superDispatchTouchEvent(ev)) {        return true;    }    return onTouchEvent(ev);}
  • 首先判断MotionEvent是不是ACTION_DOWN,如果是的话,执行onUserInteraction()方法:

      // 空方法,让子类实现  public void onUserInteraction() {      // 当此activity在栈顶时,触屏点击按home,back,menu键等都会触发此方法。      // 下拉statubar、旋转屏幕、锁屏不会触发此方法      // 所以它会用在屏保应用上,因为当你触屏机器 就会立马触发一个事件,而这个事件又不太明确是什么,正好屏保满足此需求。  }
  • getWindow()会返回PhoneWindow对象(PhoneWindow类是Window抽象类的唯一实现子类),调用PhoneWindow#superDispatchTouchEvent(ev):

      @Override  public boolean superDispatchTouchEvent(MotionEvent event) {      return mDecor.superDispatchTouchEvent(event);  }
  • mDecor是DecorView的实例,是视图的顶层View。DecorView继承自FrameLayout,那么它的父类就是ViewGroup了,而super.dispatchTouchEvent(event)方法,其实就应该是ViewGroup的dispatchTouchEvent()方法

      // This is the top-level view of the window, containing the window decor.  private DecorView mDecor;  public class DecorView extends FrameLayout implements RootViewSurfaceTaker, WindowCallbacks {      ...  }

小结
  • 当一个点击操作发生时,事件的传递顺序为:Activity -> Window -> DecorView,DecorView一般就是当前界面的底层容器(即setContentView所设置的View的父容器)

2、Activity#onTouchEvent源码解析

public boolean onTouchEvent(MotionEvent event) {    if (mWindow.shouldCloseOnTouch(this, event)) {        finish();        return true;    }    return false;}
shouldCloseOnTouch
public boolean shouldCloseOnTouch(Context context, MotionEvent event) {    // 判断mCloseOnTouchOutside标记及是否为ACTION_DOWN事件    // 同时判断event的x、y坐标是不是超出Bounds,    // 然后检查DecorView是否为空    if (mCloseOnTouchOutside && event.getAction() == MotionEvent.ACTION_DOWN            && isOutOfBounds(context, event) && peekDecorView() != null) {        return true;    }    return false;}
小结
  • 一个点击操作要是没有被Activity下的任何View处理,即顶层DecorViewdispatchTouchEvnent()方法返回false的话,则ActivityonTouchEvent()方法会被调用。

更多相关文章

  1. android SDK2.3 更新改动翻译
  2. android SDK2.3 更新改动翻译
  3. 修改android 睡眠的时间的两种方法
  4. Android单元测试初探——Instrumentation
  5. android——Serializable & Parcelable
  6. Android之——自定义TextView
  7. Android位图总结
  8. android ndk 开发之 在 应用程序中使用 jni
  9. Android中webView与h5交互

随机推荐

  1. Android(安卓)之 SQLite数据库的使用
  2. Android图形系统的分析与移植--一、Andro
  3. Android(安卓)TextView内容过长加省略号
  4. Android图形系统的分析与移植--一、Andro
  5. Android(安卓)并发之CAS(原子操作)简单介绍
  6. Android(安卓)Webview 和Javascript交互,
  7. Android之相对布局
  8. Android调用输入法软键盘,返回输入的内容
  9. Android(安卓)API 中文(13) —— ToggleBut
  10. Android(安卓)已发行多年,移动 App 已经趋