Android事件分发机制及问题解答

         以下分析仅仅是对源码的分析,当然,如果是自定义了事件的分发,那么就需要另外讨论了。
  1. 正常触发一个View的事件流程是什么?
    1. 当触发屏幕的触摸事件的时候,首先通过Activity分发事件,交给PhoneWindow分发事件,接着交给DecorView分发事件,紧接着就调用了ViewGroup( DecorView 父类方法)的分发事件,然后通过dispatchTransformedTouchEvent来给子View分发事件,最终交个View的分发事件,然后就是事件的处理了onTouchEvent。
  2. Activity的分发事件是从哪里传递过来的?
    1. http://blog.csdn.net/stonecao/article/details/6759189
  3. 事件分发的触发条件是什么?
    1. 也就是在触摸按下的时候就进行事件分发了,直到触摸取消或者抬起为一个事件分发周期
  4. 如何拦截Activity的触摸事件?
    1. dispatchTouchEvent返回true,如果需要处理事件在子视图中的分发需要super.dispatchTouchEvent或者自定义事件分发
    2. 原因:在Activity的dispatchTouchEvent中,onTouchEvent的触发条件是,子视图的dispatchTouchEvent返回false
    3. onTouchEvent始终返回true
    4. 原因:通过View.dispatchTouchEvent可以在得知,如果满足onTouchEvent返回true,那么就能保证View.dispatchTouchEvent可以返回true,这个时候就能达到屏蔽Activity的onTouchEvent了
  5. dispatchTouchEvent的作用?
    1. 负责当前VIew的事件分发操作 例如接下来的事件拦截事件处理,这些都是系统默认写好的
    2. 表明当前View的事件消费状态
    3. 返回值含义:应用层代表事件是否允许交给Activity消费
    4. 场景:例如一个视图A接受触摸事件,默认情况下,Activity也是可以收到事件的,如果不想让Activity也接收到事件,那么就将这个值设置为true
  6. onInterceptTouchEvent的作用?
    1. 其返回值决定了是否拦截事件向子视图的分发,也就是触发子视图的事件分发方法
    2. true:代表不想下分发,自己处理事件  例如:当触发屏幕某个位置时候,不像让当前位置的子视图接收到事件
    3. false:代表向下分发,自己不接受事件
  7. onTouchEvent的作用?
    1. 处理触摸事件的响应方式 例如:操作视图平移 缩放等一系列操作
  8. onTouchEvent的返回值有什么作用?
    1. 决定了View.dispatchTouchEvent的返回值状态,也间接影响了事件的最终消费对象
  9. requestDisallowInterceptTouchEvent的作用?
    1. 决定onInterceptTouchEvent是否执行 参数:true执行 false不执行
  10. 为什么重写子视图的super.onTouchEvent(event)/ 返回false的时候,在移动时候父视图的onInterceptTouchEvent就不会执行?
    1. super.onTouchEvent(event)默认情况下返回的本身就是false
    2. 首先:满足onInterceptTouchEvent执行的条件是按下事件 第一次触摸目标mFirstTouchTarget不为空 允许拦截事件标识,
    3. 其次:第一个条件是不满足的排除,而第二个不为空的触发是addTouchTarget,因为onTouchEvent返回了false,经过一系列的传递dispatchTransformedTouchEvent也返回了false,这个时候就不能触发addTouchTarget也就是说mFirstTouchTarget =null,所以就不能执行了onInterceptTouchEvent,默认情况下disallowIntercept = false。
  11. 默认情况下:如何实现父类不拦截,让子类处理onTouchEvent?
    1. 首先:让子视图的onTouchEvent返回true,但是这种情况下父视图的onInterceptTouchEvent会执行一次,如果这里没有方法其实也没什么,如果也做了处理,那么就还需要再次处理,根据问题9可以知道以下解决方案。
    2. 其次:通过down的时候通过parent.requestDisallowInterceptTouchEvent(true)在抬起或者取消的时候parent.requestDisallowInterceptTouchEvent(false)
    3. 另一种方法:在dispatchTouchEvent中super.dispatchTouchEvent之后进按下时候行parent.requestDisallowInterceptTouchEvent(true)就可以达到父类不拦截事件
  12. 为什么重写DispatchTouchEvent直接返回true/false都不能分发事件?
    1. 事件分发的目的是为了交给指定的View通过onTouchEvent进行事件消费处理。而如果直接返回true/false,其过程并没有对onInterceptTouchEvent和onTouchEvent进行处理,所以也就不能进行事件分发处理了。
    2. 而返回值的意义是 :获取当前View的事件消费状态 最终决定Activity是否消费事件  比如都不消费就交给Activity的onTouchEvent是否处理   
  13. 为什么要在super.dispatchTouchEvent之后进行请求父类是否拦截?
    1. 因为:在super.dispatchTouchEvent中,每次的DOWN事件都会重新将拦截事件标识改为拦截事件,因此在这个方法之后的DOWN重新设置为不拦截,那么之后的MOVE等事件就能达到不拦截的目的
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值