View的事件分发机制

一、点击事件的传递规则
     点击事件的分发:对MotionEvent事件的分发过程,也 即当一个MotionEvent产生时,系统需要将其传递给一个具体的View来处理,这个过程即为分发过程;
1.1 3个重要方法
     public boolean dispatchTouchEvent(MotionEvent ev)
     用来进行事件分发。 返回结果受当前view的onTouchEvent和下级View的dispatchTouchEvent方法的影响,表示是否消费该事件。
1.1.1 事件分发何时终止
     1)return true: 事件分发给当前View并由dispatchTouchEvent进行消费, 同时事件会停止向下传递;
     2)return fasle: 事件会分发给事件源Activity或者父级的onTouchEvent进行消费, 停止分发;
    3)return super.dispatchTouchEvent,事件会自动分发给当前view的onInterceptTouchEvent方法
     public boolean onInterceptTouchEvent(MotionEvent ev)
     在上述dispatchTouchEvent方法内调用 用来判断是否拦截某事件。返回结果表示是否拦截当前事件。
1.1.2 事件拦截何时终止
1)return  true:则表示事件进行拦截,并将拦截到的事件交由当前View的onTouchEvent进行处理;
    2)return false:则表示事件放行,当前View上的事件会被传递到子View中,再由子View的dispatchTouchEvent开始对事件进行分发;
    3)return super.onInterceptTouchEvent,事件默认会被拦截,并将拦截到的事件交由当前View的onTouchEvent进行处理;
public boolean onTouchEvent(MotionEvent ev)
     在dispatchTouchEvent方法内调用 用来处理点击事件,返回结果表示是否消费当前事件; 如果不消费,则在同一事件序列中,当前view无法再次接收到事件;
1.1.3 事件消费何时终止    
1)return true:则表示接收并消费当前事件;
    2)return false:则表示该事件会向上传递,并由上层View的onTouchEvent来接收;如果传递到上层的onTouchEvent还是返回false,说明该事件无效,而且接收不到下一次事件;
    3)return super.onTouchEvent:跟返回false相同;
这3个方法的关系如下:

     1)对于ViewGroup来说,点击事件产生后,首先会传递给它,这时它的 dispatchTouchEvent 方法被调用,如果这个viewgroup的 onInterceptTouchEvent方法返回true表示此viewgroup要拦截当前事件,接着事件会被它的onTouchEvent处理;如果这个viewgroup的onInterceptTouchEvent方法返回false表示它不拦截当前事件,此时事件会继续传递给它的子元素处理,接着 子元素的 dispatchTouchEvent被调用
     2)对于view来说,如果view设置onTouchListener,那么此时onTouchListener的onTouch方法会被回调;这时事件如何处理跟onTouch方法返回值有关:如果返回false,则当前view的onTouchEvent方法被调用;如果返回true,onTouchEvent方法不会被调用----> view的onTouchListener优先级比onTouchEvent高。
     3)MotionEvent事件产生后,其传递顺序:Activity--->Window---->View;
     4)ViewGroup默认不拦截任何事件;
     5)View没有onInterceptTouchEvent方法,一旦点击事件传递给它,其onTouchEvent方法会立刻被执行;
     6)View的onTouchEvent默认都会消费该事件;
二、事件分发的源码解析
2.1 Activity对点击事件的分发过程
     当MotionEvent事件发生时,该事件最先传递给当前Activity,此时由Activity的 dispatchTouchEvent 进行事件分发: 具体工作是由Activity内部window来完成,然后window才把事件交给DecorView来处理(最顶级view);

  1)事件开始 交给window进行分发 :见第二个if中的 superDispatchTouchEvent方法; 该方法返回true,说明事件已经消费;返回false说明事件没有消费,这时Activity的onTouchEvent方法被调用;
2.2 Window如何将事件传递给ViewGroup
    Window是抽象类,同时superDispatchTouchEvent方法也是抽象方法---> Window类的具体实现类是PhoneWindow,在PhoneWindow类中 superDispatchTouchEvent具体实现了将事件传递给DecorView。 源代码如下:

2.3 顶级View对点击事件的分发过程
    1)首先看ViewGroup对点击事件的分发过程:也即dispatchTouchEvent(MotionEvent ev)方法被调用,第一步查看点击事件是否被拦截;如果拦截,就自己处理;如果不拦截,就交给它的子View来消费事件;
2)viewgroup不拦截事件时, 会遍历viewgroup的所有子元素,然后判断子元素是否能够接收到点击事件,标准:子元素是否在播动画和点击事件坐标是否落在子元素区域。
     如果满足这两个条件,事件会传递给它处理。
 2.4 View对点击事件的处理过程
   1)较为简单,因为其没有子元素无法向下传递事件,也即 view只能消费事件;
     2)判断view有没有设置OnTouchListener, 如果设置OnTouchListener而且onTouch方法返回true,此时view的onTouchEvent不会被调用,此时view的dispatchTouchEvent返回true;如果没有设置OnTouchListener以及onTouch方法返回false,view的onTouchEvent被调用。
3)onTouchEvent实现:只要View的CLICKABLE和LONG_CLICKABLE有一个为true,那么view就会消耗此事件,此时onTouchEvent方法返回true;然后在ACTION_UP事件发生时,会触发performClick方法,如果View设置OnClickListener,那么在performClick中调用onClick方法。
    
    
    
    
    
    
    
    
    
    
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
YOLO高设计资源源码,详情请查看资源内容中使用说明 YOLO高设计资源源码,详情请查看资源内容中使用说明 YOLO高设计资源源码,详情请查看资源内容中使用说明 YOLO高设计资源源码,详情请查看资源内容中使用说明YOLO高设计资源源码,详情请查看资源内容中使用说明YOLO高设计资源源码,详情请查看资源内容中使用说明YOLO高设计资源源码,详情请查看资源内容中使用说明YOLO高设计资源源码,详情请查看资源内容中使用说明YOLO高设计资源源码,详情请查看资源内容中使用说明YOLO高设计资源源码,详情请查看资源内容中使用说明YOLO高设计资源源码,详情请查看资源内容中使用说明YOLO高设计资源源码,详情请查看资源内容中使用说明YOLO高设计资源源码,详情请查看资源内容中使用说明YOLO高设计资源源码,详情请查看资源内容中使用说明YOLO高设计资源源码,详情请查看资源内容中使用说明YOLO高设计资源源码,详情请查看资源内容中使用说明YOLO高设计资源源码,详情请查看资源内容中使用说明YOLO高设计资源源码,详情请查看资源内容中使用说明YOLO高设计资源源码,详情请查看资源内容中使用说明YOLO高设计资源源码,详情请查看资源内容中使用说明YOLO高设计资源源码,详情请查看资源内容中使用说明YOLO高设计资源源码,详情请查看资源内容中使用说明YOLO高设计资源源码,详情请查看资源内容中使用说明YOLO高设计资源源码,详情请查看资源内容中使用说明YOLO高设计资源源码,详情请查看资源内容中使用说明YOLO高设计资源源码,详情请查看资源内容中使用说明

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值