自学Android开发 View的事件分发机制

追求适度,才能走向成功;人在顶峰,迈步就是下坡;身在低谷,抬足既是登高;弦,绷得太紧会断;人,思虑过度会疯;水至清无鱼,人至真无友,山至高无树;适度,不是中庸,而是一种明智的生活态度。

导读:本篇文章讲解 自学Android开发 View的事件分发机制,希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com,来源:原文

目录

一、触摸事件分析

二、事件分发

1、dispathTouchEvent(MotionEvent event)

2、onInterceptouchEvent(MotionEvent ev)

3、onTouchEvent(MotionEvent event)

4、三个方法的关系

三、关于事件分发机制

四、activity中的事件分发


一、触摸事件分析

        任何事物都有一个起点,触摸事件也是如此。当手指触摸手机的屏幕后发生什么呢?首先是由Linux内核调用触摸屏驱动,然后触摸屏驱动通知Android OS 的HAL层的相关Library,最后相关的Library会通知位于应用层的程序。

二、事件分发

        事件分发就是对MotionEvent事件的分发过程,当一个MotionEvent事件产出后系统就需要把这个事件传递给一个具体的View,而这个传递的过程就是事件分发。分发过程由这几个方法完成:dispathTouchEvent、onInterceptouchEvent、onTouchEvent。

1、dispathTouchEvent(MotionEvent event)

        用来进行事件的分发。如果事件能够传递给当前View,那它一定会会被调用,返回结果受当前View的onTouch和下一级的View的dispathTouchEvent方法的影响,表示是否消耗当前事件。

2、onInterceptouchEvent(MotionEvent ev)

        在dispathTouchEvent方法内部调用,用来判断是否拦截某个事件,如果当前View拦截了某个,那在同一个事件序列当中,此方法不会被再次调用,返回结果表示是否拦截当前事件。

3、onTouchEvent(MotionEvent event)

        也是在dispathTouchEvent方法内部调用,用来处理事件,返回结果表示是否消耗当前事件,如果不消耗,则在同一个事件序列中,当前View无法再次接收事件。

4、三个方法的关系

//这个是伪码 不是源码
public boolean dispathTouchEvent(MotionEvent event){
  boolean result = false;
  if(onInterceptTouchEvent(event)){
      result = onTouchEvent(event);
  }else{
      result = child.dispathTouchEvent(event);
}
return result;
}

通过上面的伪码已经完全表示出它们的关系。

三、关于事件分发机制

1、同一个事件序列是指从DOWN事件开始,中间伴随着数个MOVE事件,最终以UP事件结束。

2、正常的情况下,一个事件序列只能被一个View拦截且消耗。因为一旦一个View拦截了某事件,那么同一个事件序列的内的所有事件都会交给它处理,因此同一个事件中的事件不能分发给两个View的同时处理。

3、某个View一旦拦截了,那么这一个事件序列只能由它处理,且它的onInterceptouchEvent不会调用了。

4、某个View一旦开始处理事件,如果它不消耗DOWN事件,那么同一个事件序列的其他事件都不会交给它了,并且事件将重新交给它的父元素去处理。

5、Viewgroup默认不拦截任何事件。

6、View没有onInterceptouchEvent方法。

7、View的onTouch默认否会消耗事件。

8、事件传递是由外向内的,事件总是先传递给父元素然后由父元素分发给子元素,通过requestDisallowInterceptTouchEvent分发可以在子元素中干预父元素的事件分发的过程,但是DOWN事件除外。

9、事件传递遵循:activity-> window->View。

四、activity中的事件分发

activity的dispatchTouchEvent的源码

publick boolean dispatchTouchEvent(event){
   if(event.getAction() == MotionEvent.ACTION_DOWN){
     onUserInteraction();
   }
   if(getWindow().superDispatchTouchEvent(event)){
      return true;
   }

return onTouchEvent(event);

}

        第一步是判断事件如果是点击事件,则调用 onUserInteraction 方法,该方法的方法体为空,可以重写这个方法,用于处理一些交互问题。

        第二步是调用了 Window 的 superDispatchTouchEvent 方法,如果返回 true,则表示此事件已被消费,结束此次分发流程,false 则继续调用该 Activity 的 onTouchEvent 方法处理该事件。

如果感觉对您有意义,就给博主一些鼓励(点赞、关注、收藏),如果有错误欢迎大家评论。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/128361.html

(0)
飞熊的头像飞熊bm

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!