谈谈我所理解的事件分发机制

        事件分发机制基本上遵从Activity->ViewGroup->View的顺序进行事件分发,通过调用onTouchEvent()方法进行事件处理。事件分发机制中关键的三个方法就是dispatchTouchEvent()、onTouchEvent()和onInterceptTouchEvent()。其中dispatchTouchEvent()方法是负责事件分发的,onTouchEvent()是进行事件处理的,onInterceptTouchEvent()是负责事件拦截的。事实上,Android的事件分发机制也就是指Activity的事件分发机制、ViewGroup的事件分发机制和View的事件分发机制。

     

Activity的事件分发机制:

        当DOWN事件产生后,即点击事件产生后,事件首先会传给当前的Activity,这时会调用Activity的dispatchTouchEvent()方法。当DOWN事件产生时,会调用onUserInteraction()这个方法,这个方法的主要作用是实现屏保功能,并且当Activity在栈顶时,触屏、点击HOME、BACK键都会触发此方法。然后在Activity的dispatchTouchEvent()方法中有一个getWindow().superDispatchTouchEvent(ev)的判断条件,如果该条件成立,也就是说返回true,则该事件就停止传递了。也就意味着结束了本次的事件分发。否则的话便返回onTouchEvent(ev),此时事件就会继续向下分发。而这个判断条件实际上是调用了DecorView的superDispatchTrackBallEvent()方法。而DecorView是继承自FrameLayout的,FrameLayout是ViewGroup的子类,所以事实上是直接调用了ViewGroup的dispatchTouchEvent()方法。

ViewGroup的事件分发机制:

        ViewGroup的dispatchTouchEvent()方法中,定义了一个Boolean类型的变量intercept,表示是否要拦截事件。其中通过onInterceptTouchEvent(ev)方法对intercept进行赋值,大多数情况下返回的是false,但我们可以通过重写onInterceptTouchEvent(ev)来改变它的返回值,在ViewGroup的dispatchTouchEvent()方法内部做了一个for循环,通过倒序遍历ViewGroup下面的子View,然后一个一个判断点击的位置是否是该子View的布局区域。

View的是事件分发机制:

        View的dispatchTouchEvent()方法中,满足这三个条件时,才会返回true。其中第一个条件mOnTouchListener不为空,调用setOnTouchListener,第二个条件是判断当前点击的控件是否为enable,第三个条件是调用setOnTouchListener()时覆盖onTouch()方法的返回值。在View的onTouchEvent()中,只要View的CLICKABLE和LONG_CLICKABLE有一个为true,onTouchEvent()就会返回true进行事件的消耗。在UP事件发生时会调用perforclick()方法。


下面是按照自己的理解进行绘制的一个有关事件分发机制的一个图。



总结:

1、关于Android事件分发机制,相关方法的方法有三个:onTouchEvent(),dispatchTouchEvent()和onInterceptTouchEvent(),而相关的类有Activity,View,ViewGroup。时间的分发顺序是按照dispatchTouchEvent--->onInterceptTouchEvent ---> onTouchEvent的顺序执行的。

 2、事件的传递从Activity的dispatchTouchEvent()方法开始的。

 3、onTouch()方法优先级高于onTouchEvent(ev)方法。onTouch()执行总优先于onClick()。

4、Android事件分发机制中,主要有两个过程,一个是向下分发的过程,该过程主要调用dispatchTouchEvent(),还有一个是向上返回的过程,主要依靠onTouchEvent()方法。

5、Android事件是从父view向子view分发的,如果事件被拦截,则事件不会继续向下分发,而是在当前所在层被消耗/处理。此时向下分发过程会提前结束,没有被消耗的事件,从父view向子view逐级分发,最后又回到Activity,被Activity中的onTouchEvent()消耗/处理。此时向上返回的过程也就提前结束了。

        


  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
浏览器的事件轮询机制是指浏览器在等待事件发生时,采用轮询的方式来检查是否有事件发生。这个机制是浏览器实现异步编程的重要手段之一。在浏览器中,事件可以是用户交互、网络请求、定时器等等。浏览器通过事件队列来管理这些事件,当事件发生时,会将事件加入到事件队列中,然后等待 JavaScript 引擎执行。 事件轮询机制的实现方式是通过一个事件循环来实现的。事件循环会不断地从事件队列中取出事件,然后执行相应的回调函数。当事件队列为空时,事件循环会进入休眠状态,等待新的事件加入到事件队列中。这个过程是不断重复的,直到浏览器关闭。 在事件轮询机制中,有一个重要的概念叫做“任务队列”。任务队列是一个存放任务的队列,每个任务都是一个回调函数。当事件发生时,会将相应的回调函数加入到任务队列中。任务队列分为两种类型:宏任务和微任务。宏任务包括用户交互、网络请求、定时器等等,而微任务则是指 Promise 的回调函数、MutationObserver 的回调函数等等。 在事件轮询机制中,宏任务和微任务的执行顺序是不同的。当一个宏任务执行完毕后,会立即执行所有的微任务,然后再执行下一个宏任务。这个过程是不断重复的,直到事件队列为空。 总的来说,浏览器的事件轮询机制是一种非常重要的机制,它可以帮助我们实现异步编程,提高程序的性能和用户体验。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值