事件分发概念及其流程:

1.事件分发:

  • 通过手指对屏幕的触摸完成整个交互的过程
  • 用户通过屏幕与手机交互的时候,每一次点击、长按、移动等都是一个事件
  • 事件分发机制就是某一个事件从屏幕传递给各个view,由view来使用这一事件(消费事件)或忽略这一事件(不消费),这个整个过程的控制。

2.那么事件分发的对象是谁?

系统把事件封装为MotionEvent对象,事件分发的过程就是MotionEvent分发的过程。

3. 事件的类型:

  • ACTION_DOWN 按下
  • ACTION_MOVE 移动
  • ACTION_UP 抬起
  • ACTION_CANCEL 取消

4. 事件序列:

从手指按下屏幕开始,到手指离开屏幕所产生的一系列事件。

5.传递层级:

activity不负责处理视图的控制,而是负责处理生命周期和处理事件。

真正控制视图是window,一个activity包含一个window.window中包含了一个DecorView,是顶级view.serContentview设置的就是DecorView的子元素。view的事件都会先经过DecorView然后传递给我们的view

  • Activity------>Window ------>DecorView------->ViewGroup---------->View

6.主要传递对象:

  • Activity
  • ViewGroup
  • View

Activity的事件分发流程图:

Android(复习篇): 事件分发机制


走源码

1. Activity:

  • dispatchTouchEvent(MotionEvent event)
  • onTouchEvent(MotionEvent event)

Android(复习篇): 事件分发机制

Android(复习篇): 事件分发机制

当当前手指按下的时候,就调用onUserInteraction(),.

Android(复习篇): 事件分发机制

其默认是空方法.onUserInteraction()会在真个事件开始的时候立刻调用。可重写该方法,侦听方法的开始。

Android(复习篇): 事件分发机制

这里开始正式进入事件的分发过程。

如果返回true,则事件传递结束,如果false,则会调用return onTouchEvent(ev);

Android(复习篇): 事件分发机制

Android(复习篇): 事件分发机制

Android(复习篇): 事件分发机制

发现都是抽象方法。方法的具体实现是在

Android(复习篇): 事件分发机制

Android(复习篇): 事件分发机制

Android(复习篇): 事件分发机制

Android(复习篇): 事件分发机制

Android(复习篇): 事件分发机制

其实就是添加到了DecorView.所以它是最顶层的view.

Android(复习篇): 事件分发机制

即调用了父类FrameLayout的dispatchTouchEvent()

Android(复习篇): 事件分发机制

Android(复习篇): 事件分发机制

搜了一下,发现并没有这个方法。

Android(复习篇): 事件分发机制

Android(复习篇): 事件分发机制

原来是在其ViewGroup里实现的。

这样

getWindow().superDispatchTouchEvent(ev)的大致流程就走完了。其返回值要看ViewGroup的返回值。

当返true,就表示消费了,就不会再调用Activity的OnTouchEvent()

Android(复习篇): 事件分发机制

 

如果getWindow().superDispatchTouchEvent(ev)返回为false,则说明当前任何视图都未能处理掉这个触摸事件,这个时候才会去调用:

Android(复习篇): 事件分发机制

Android(复习篇): 事件分发机制

先判断是不是调用了mWindow.shouldCloseOnTouch();返回true就会关闭掉当前的activity并返回true,表示已消费。

Android(复习篇): 事件分发机制

当mCloseOnTouchOutside为true表示当前activity表示支持点击空白区域让activity进行消失的。【当activity以download的形式该变量才h会为true】

当phoneWindow下的peekDecorView() != null的时候也返回true.

Android(复习篇): 事件分发机制

当isOutSide为true时,表示当前点击事件在DecorView之外,也返回true。

返回true就会关闭掉aactivity并标记消费了事件,否则onTouchEvent的返回值会作为dispatchTouchEvent的返回值。

2. ViewGroup

接上面的源码分析,看看ViewGroup如何在源码之间进行分发的。

  • dispatchTouchEvent(MotionEvent e)
  • onInterceptTouchEvent(MotionEvent e)
  • onTouchEvent(MotiionEvent e)【view里才有,ViewGroup没有】

流程图:

Android(复习篇): 事件分发机制

源码过于长,,可自己查看源码对照流程图

总结:viewgroup的dispatcjhTouchEvent做的几件事:

  • 去判断是否需要拦截事件
  • 在当前viewgroup中找到用户真正点击的view
  • 分发事件到view上

3. View事件的分发流程:

  • dispatchTouchEvent(MotionEvent ev)
  • onTouchEvent(MotionEvent ev)

Android(复习篇): 事件分发机制

Android(复习篇): 事件分发机制

Android(复习篇): 事件分发机制

这段是Google为障碍人士提供的服务,不管。

Android(复习篇): 事件分发机制

如果是按下事件就停止嵌套的滚动。

Android(复习篇): 事件分发机制

这一段代码就进入了事件分发, 首先判断是否符合安全策略。

符合安全策略后,就判断当前的事件是否是通过鼠标进行的滚动条的拖动。

如果是的话就直接为消费了事件。

然后是判断是否注册了onTouch()表示被消费。

然后综合result和onTouchevent()来判断最后的返回结果result.

核心逻辑是:Android(复习篇): 事件分发机制

 

而下面的代码和事件分发没多大关系:

Android(复习篇): 事件分发机制

 

所以把焦点放到:

Android(复习篇): 事件分发机制

Android(复习篇): 事件分发机制

首先获取触摸的位置、当前view的标志、是否是可点击状态。

Android(复习篇): 事件分发机制

如果当前view是禁用状态的话,onTouchEvent的返回值就直接等于可点击的状态。

Android(复习篇): 事件分发机制

然后判断view是否设置了触摸代理,如果设置了代理,其onTouchEvent返回为true则事件被消费。

Android(复习篇): 事件分发机制

TOOLTIP是Android 8以上添加的消息提示的工具。长按视图或鼠标悬停视图上,消息就会显示在视图的附近。类似Flutter的FloatActionButton的tooltip属性。


流程验证及案例演示:

验证准备:

Android(复习篇): 事件分发机制

Android(复习篇): 事件分发机制

Android(复习篇): 事件分发机制

Android(复习篇): 事件分发机制

Android(复习篇): 事件分发机制

Android(复习篇): 事件分发机制

开始验证:

默认传递流程:

MainActivity:  dispatchTouchEvent:  -> 
MyViewGroup:  dispatchTouchEvent  => 
MyViewGroup:  onInterceptTouchEvent:->(默认viewgroup不会拦截)->
MyView:  dispatchTouchEvent:->(myview里没有注册onTouchEvent的接口)->
MyView:  onTouchEvent->由于view的默认返回false,所以事件向上传递调用myviewgroup的onTouchevent,其返回值还是默认为false->
MainActivity:  onTouchEvent:.

点击myview:

Android(复习篇): 事件分发机制

Android(复习篇): 事件分发机制

在同一个事件序列下,子view(viewgroup)已经没有处理的事件(没有消费事件)的情况下,事件默认不会进入子view中。【后续事件就不会再传递到子view中】

此时:

MainActivity:  dispatchTouchEvent-->
MainActivity:  onTouchEvent

Android(复习篇): 事件分发机制

验证cancel事件:

Android(复习篇): 事件分发机制

Android(复习篇): 事件分发机制

Android(复习篇): 事件分发机制

Android(复习篇): 事件分发机制

按下并不松手滑动。

Android(复习篇): 事件分发机制

 

Android(复习篇): 事件分发机制

Android(复习篇): 事件分发机制

验证ViewGroup事件的拦截:

Android(复习篇): 事件分发机制

用第一个布局。

即验证不会传递到Myview。并事件会一直传递到Myviewgroup并后续事件让它消费.

 

 

 

相关文章:

  • 2022-01-20
猜你喜欢
  • 2022-12-23
  • 2021-10-27
  • 2021-11-17
  • 2021-04-08
  • 2021-08-17
相关资源
相似解决方案