重写Android事件分发机制

Android事件分发机制,也被称为“事件处理机制”,“Touch处理机制”等等,指的是对用户触摸屏幕后引发的一系列Touch事件的处理机制,例如用户点击一次屏幕,该事件到底是页面上的哪个View来处理,为什么?MotionEvent事件主要有:down,move,up主要分析的类:ViewGroup,View和特殊的View(ListView,ScrollView等)主要分析的方法:d...
摘要由CSDN通过智能技术生成

Android事件分发机制,也被称为“事件处理机制”,“Touch处理机制”等等,指的是对用户触摸屏幕后引发的一系列Touch事件的处理机制,例如用户点击一次屏幕,该事件到底是页面上的哪个View来处理,为什么?

MotionEvent事件主要有:down,move,up

主要分析的类:ViewGroup,View和特殊的View(ListView,ScrollView等)

主要分析的方法:dispatchTouchEvent,onInterceptTouchEvent,onTouchEvent

知识背景

Activity管理着一个Window,具体的实现类PhoneWindow,PhoneWindow里面有个DecorView的对象,DecorView分为两部分,title和content。我们在Activity里面调用setContentView,就是给content部分加载布局

事件传递流程源码分析(API 27)

  • 先看Activity.java,在dispatchTouchEvent中,会执行getWindow().superDispatchTouchEvent(ev),调用mWindow的superDispatchTouchEvent(ev),即将事件传递给PhoneWindow
// Activity.java
public boolean dispatchTouchEvent(MotionEvent ev) {
   
    if (ev.getAction() == MotionEvent.ACTION_DOWN) {
   
        onUserInteraction();
    }
    // getWindow()放回mWindow对象,调用mWindow的superDispatchTouchEvent
    if (getWindow().superDispatchTouchEvent(ev)) {
     
        return true;
    }
    return onTouchEvent(ev);
}

public Window getWindow() {
   
    return mWindow;   
}

private Window mWindow;  // PhoneWindow是Window的唯一实现类

final void attach(...) {
   
    ...
    // 给mWindow赋值
    mWindow = new PhoneWindow(this, window, activityConfigCallback);      ...
}
  • 在PhoneWindow中又直接将事件传递到DecorView的superDispatchTouchEvent
// PhoneWindow.java
@Override
public boolean superDispatchTouchEvent(MotionEvent event) {
   
	// 调用mDecor的方法
    return mDecor.superDispatchTouchEvent(event);  
}

// This is the top-level view of the window, containing the window decor.
private DecorView mDecor;  // 申明

public PhoneWindow(...) {
   
    ...
    mDecor = (DecorView) preservedWindow.getDecorView();  // 初始化
    ...    
}
  • DecorView调用父类ViewGroup的superDispatchTouchEvent
// DecorView.java
public boolean superDispatchTouchEvent(MotionEvent event) {
   
    // DecorView继承FrameLayout,而FrameLayout没有重写dispathToucheEvent,所以这里将会调用FrameLayout的父类ViewGroup的dispatchTouchEvent
    return super.dispatchTouchEvent(event);
}
  • ViewGroup部分源码,主要方法dispatchTouchEvent,dispatchTransformedTouchEvent
// ViewGroup.java
public boolean dispatchTouchEvent(MotionEvent ev) {
   
    ...
    // Handle an initial down.
    if (actionMasked == MotionEvent.ACTION_DOWN) {
   
        // Throw away all previous state when starting a new touch gesture.
        // The framework may have dropped the up or cancel event for the previous gesture
        // due to an app switch, ANR, or some other state change.
        cancelAndClearTouchTargets(ev);
        // 每次ACTION_DOWN,都会通过resetTouchState,将mFirstTouchTarget和mGroupFlags重置
        resetTouchState(); 
    }

    // Check for interception ====================================
    final boolean intercepted;  // 申明局部变量intercepted标记事件是否要拦截
    if (actionMasked == MotionEvent.ACTION_DOWN
            || mFirstTouchTarget != null) {
   
        final boolean disallowIntercept = (mGroupFlags & FLAG_DISALLOW_INTERCEPT) != 0;
        
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值