前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Activity 事件分发

Activity 事件分发

作者头像
Yif
发布2019-12-26 15:08:23
8300
发布2019-12-26 15:08:23
举报
文章被收录于专栏:Android 进阶Android 进阶
undefined
undefined

Activity dispatchTouchEvent 分析

首先先判断当前事件是否是Down事件,如果是就调用onUserInteraction方法,如果不是就不会调用,所以Up,Move方法不会调用该方法。

代码语言:javascript
复制
public boolean dispatchTouchEvent(MotionEvent ev) {
    if (ev.getAction() == MotionEvent.ACTION_DOWN) {
        onUserInteraction();
    }
    if (getWindow().superDispatchTouchEvent(ev)) {
        return true;
    }
    return onTouchEvent(ev);
}

Activity的attach源码:

代码语言:javascript
复制
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

代码语言:javascript
复制
@Override
    public boolean superDispatchTouchEvent(MotionEvent event) {
        return mDecor.superDispatchTouchEvent(event);
    }

这里mDecorDecorView对象,通过查看DecorView类的

代码语言:javascript
复制
public boolean superDispatchTouchEvent(MotionEvent event) {
        return super.dispatchTouchEvent(event);
    }

由于DecorView继承自FragmentLayout public class DecorView extends FrameLayout FragmentLayout又继承自viewGroup public class FrameLayout extends ViewGroup 所以调用的就是viewgroupdispatchTouchEvent方法 综上: ActivitygetWindow().superDispatchTouchEvent(ev)就是调用的Viewgroup dispatchTouchEvent方法

Window PhoneWindow与DecorView

  1. Window:是一个抽象基类,作用于外观用户界面和行为策略表示一个窗口,它包含一个View tree和窗口的layout 参数。View tree的root View可以通过getDecorView得到。还可以设置Window的Content View。其实现类是PhoneWindow。Activity,Dialog,Toast,都包含一个Window,该Window在Activity的attach()函数中mWindow = new PhoneWindow(this)创建。
  2. DecorView:该类是PhoneWindow类的内部类,继承自FrameLayout,它是所有应用窗口的根View,PhoneWindow设置DecorView为应用窗口的根视图。
  3. PhoneWindowPhoneWindow对象帮我们创建了一个PhoneWindow内部类DecorView(父类为FrameLayout)窗口顶层视图

dispatchTouchevent 总结

  1. 所有的事件分发都是首先从ActivitydispatchTouchEvent方法开始
  2. 然后再判断当前事件是否是down事件,是Down事件于是就调用onUserInceration方法
  3. 再通过Activity的根view,通过以上源码阅读得知就是FragmentLayout,也就是ViewGroup将事件分发给子view,接着调用Activity的setContentView方法加载view
  4. Activity下的子view拦截事件,就不会调用Activity的onTouchEvent方法;当viewgroup的dispatchTouchEvent方法返回true就直接返回,也不会调用Activity的onTouchEvent方法;当子view没有处理事件就交给viewgroup处理,如果还没有处理事件,一直向上传递,最后交给Activity来消费该事件

Activity onUserInteraction 分析

public void onUserInteraction() {} 空实现方法,简单解释:

  1. 每当Key,Touch,Trackball事件分发到当前Activity就会被调用。如果想让Activity在运行的时候,能够得知用户正在与设备交互,就可以override该方法。
  2. 回调方法和onUserLeaveHint是为了帮助Activities智能的管理状态栏Notification;特别是为了帮助Activities在恰当的时间取消Notification,就是管理通知

Activity onTouchEvent 分析

代码语言:javascript
复制
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;
}
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2019年7月19日 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Activity dispatchTouchEvent 分析
    • Window PhoneWindow与DecorView
      • dispatchTouchevent 总结
      • Activity onUserInteraction 分析
      • Activity onTouchEvent 分析
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档