android事件分发源码总结

事件分发

  1. 用户通过屏幕与手机交互的时候,每一次点击、长按、移动等都是一个事件
  2. 事件分发机制:某一个事件从屏幕传递各个View,由View来使用这一个事件(消费事件)或者忽略这一事件(不消费事件),这整个过程的控制

事件传递层级

Activity->Window->DecorView->ViewGroup->View
首先再Activity上,传递给Activity持有的window,接着传递给window持有的DecorView,DecorView继承自ViewGroup然后真正分发到ViewGroup和View上面

Activity中事件传递过程

通过方法:

  1. dispatchTouchEvent(MovtionEvent ev)
  2. onTouchEvent(MovtionEvent ev)
  • Activity事件开始的时候会首先调用dispatchTouchEvent()方法
  • 如果为事件为Down按下,Activity下有个方法会被调用(onUserInteraction()),需要用的话重新就行
  • 接下来会调用getWindow().superDispatchTouchEvent(ev)方法,从这里正式进入事件派发过程,一直会调用到ViewGroup的dispatchTouchEvent()方法
  • 如果返回为true,Activity的dispatchTouchEvent()方法也会返回为true表示事件被消费
  • 如果返回为false,就会调用Activity的onTouchEvent()方法
  • Activity的onTouchEvent()方法首先会调用Window下的shouldCloseOnTouch()方法,判断事件是否再可响应范围内,返回true和false,Activity的dispatchTouchEvent()方法的返回值等于Activity.onTouchEvent()方法返回值,并结束事件

ViewGroup事件分发

使用方法:

  1. dispatchTouchEvent()
  2. onInterceptTouchEvent()
  3. onTouchEvent()
  • 在ViewGroup.dispatchTouchEvent()方法进入
  • 然后调用onFilterTouchEventForSecurity(),判断触摸事件是否符合安全策略,返回false未消费,结束事件
  • 安全策略之后之后如果当前触摸事件是down按下事件系统会清除所有的触摸目标,并且重置触摸状态
  • 返回true执行onIntercepTouchEvent()方法,判断是否拦截(按下事件或者存在子view的时候进入逻辑)
  • 不去拦截返回false允许向子View传递,找到被点击的子View,调用子View的dispatchTouchEvent()方法,结束事件
  • 拦截返回true,不允许事件向子View传递,调用ViewGroup父类的dispatchTouchEvent()方法自己处理该事件,结束事件

ViewGroup安全策略

onFilterTouchEventForSecurity()
​ 1. 当前view是否处于被遮挡的状态,
​ 2. 当前的配置是否设置成被遮挡时过滤触摸事件

View 事件分发

  1. dispatchTouchEvent()
  2. onTouchEvent()
  • 在View.dispatchTouchEvent() 方法进入,首先判断当前的View是否具有响应的焦点,如果没有响应方法直接返回false事件未消费
  • 如果可响应返回true,执行onFilterTouchEventforSecurity(),判断触摸事件是否符合安全策略
  • 接着判断是否为鼠标事件,如果是返回true标记事件被消费
  • 如果不是鼠标事件,系统就会判断当前view是否已经注册了TouchListener(触摸监听),监听onTouch()触摸事件的返回值
  • 返回值为true事件被消费,系统就会监听view的onTuchEvent()触摸事件返回值,触摸事件的返回值,返回true被消费,false未消费结束事件

事件分发总结

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
Activity->Window->DecorView->ViewGroup->View
传递阶层:DecorView:是Activity最顶层的View视图,DecorView继承自FrameLayout,继承自ViewGroup
首先再Activity上,传递给Activity持有的window窗口,接着传递给window持有的DecorView,DecorView继承自ViewGroup然后真正分发到一个个的ViewGroup和View上面
第一部分Activity

  • Activity事件开始的时候会首先调用dispatchTouchEvent()方法
  • 如果为事件为Down按下,首先会调用onUserInteraction(),这是一个空方法需要用的话重写即可
  • 接下来会调用getWindow().superDispatchTouchEvent(ev)方法,从这里正式进入事件派发过程,一直会调用到ViewGroup的dispatchTouchEvent()方法,如果这个方法返回为true,Activity的dispatchTouchEvent()方法也会返回为true表示事件被消费
  • 如果返回为false,就会调用Activity的onTouchEvent()方法,方法首先会调用Window下的shouldCloseOnTouch()方法,判断事件是否再可响应范围内,返回true和false,返回结果等于Activity的dispatchTouchEvent()方法分发事件的返回结果

第二部分ViewGroup

  • 在ViewGroup.dispatchTouchEvent()方法进入
  • 然后调用onFilterTouchEventForSecurity(),判断触摸事件是否符合安全策略,返回false未消费,结束事件
  • 进入viewGroup,经过安全策略,之后系统会判断当前触摸事件是按下的时候会清除所有的触摸目标,并且重置触摸状态。之后系统进行检测当时触摸事件是否需要拦截(等于按下事件Down或者存在子View)
  • 返回true执行onIntercepTouchEvent()方法,判断是否拦截(按下事件或者存在子view的时候进入逻辑)
  • 不去拦截返回false允许向子View传递,找到被点击的子View,调用子View的dispatchTouchEvent()方法,结束事件
  • 拦截返回true,不允许事件向子View传递,调用ViewGroup父类的dispatchTouchEvent()方法自己处理该事件,结束事件

第三部分View

  • 在View.dispatchTouchEvent() 方法进入,首先判断当前的View是否具有响应的焦点,如果没有响应方法直接返回false事件未消费
  • 如果可响应返回true,执行onFilterTouchEventforSecurity(),判断触摸事件是否符合安全策略
  • 接着判断是否为鼠标事件,如果是返回true标记事件被消费
  • 如果不是鼠标事件,系统就会判断当前view是否已经注册了TouchListener(触摸监听),监听onTouch()触摸事件的返回值
  • 返回值为true事件被消费,系统就会监听view的onTuchEvent()触摸事件返回值,触摸事件的返回值,返回true被消费,false未消费结束事件
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值