事件分发机制

       其实用户和应用程序的交互多数都是通过触摸事件完成。android对触摸事件的处理逻辑简单概述为:从上到下传递事件,然后从下到上处理时间逻辑,其实事实我们也可以理解,在你触摸屏幕的时候,首先第一层那道事件,然后一层一层传下去,当传到具体view,如TextViewButton等时,结束传递,然后开始处理。一层一层往上传,但是在传的过程中,会根据dispatchTouchEventonInterceptTouchEvent(MotionEvent ev)onTouchEvent的返回值,导致事件的流向不同!

        事件的大概流程:当用户操作屏幕时,通过底层相关处理事件传到WindowMangerService (WMS) 类, WMS 将事件交给当前活动窗口(在栈顶端的) Activity ,当前活动窗口 Activity 拿到事件,调用当前 Activity 界面的根布局的 dispatchTouchEvent ,根 view 开始 dispatchTouchEvent 事件到具体 view
     因为触摸事件是窗口坐标值,所以需要将坐标值转换为 view 自己的坐标体系。转换结束后,使用 for 循环遍历,该 view 的所有子 view ,读取子 view 的坐标体系,即子 view 所占的大小,是个 Rect 对象,上下左右,拿到这个值后,根据上面转换好的坐标,判断点击的坐标是否包含在当前子 view 中,如果不包含,直接开始下一个子 view 如果坐标包含在子 view 中,则调用子 view dispatchTouchEvent ,如果子 view 还是 ViewGroup 类型的,那么开始从上面标有( -- 递归开始点 - )处递归调用。 直道判断这个坐标是含在具体字 View 为此, 当然了,如果这个过程中有一个 ViewGroup 对自身的 dispatchTouchEvent onInterceptTouchEvent(MotionEvent ev) onTouchEvent 方法做处理了,那么事件即可达到对对事件的控制,对事件的控制很常见,比如常见的下拉刷新、自定义侧滑框架及自定义相关特效等等都会涉及到对这个事件的控件,接下来我就简单的说下 ViewGroup 下事件传递大致情况 :( )

     ViewGroupdispatchTouchEvent事件发布的方法,true事件不下发送,返回默认值事件传递给当前控件的onInterceptTouchEvent方法,onInterceptTouchEvent是事件拦截方法,该方法返回默认值或者false时,事件直接传递给当前ViewGroupView,然后子View做相关处理,如果返回true表示拦截事件,事件不忘子View传递,直接传递给onTouchEvent方法,如果onTouchEvent方法返回默认值,事件直接用父类处理;如果返回true,事件直接被消费调;如果返回false事件将返回给上一层控件(包含控件的父布局)

那么如果要做相关效果就可以在事件传递过程中处理。

简单介绍事件传递机制:

首先在Android中,事件相应有很多比如包括:点按、长按、拖拽、滑动等,点按又可以包括单击和双击,另外还包括单指操作和多指操作。总的来说,所有的事件都是以三个部分作为基础:

·        按下(ACTION_DOWN)

·        移动(ACTION_MOVE)

·        抬起(ACTION_UP)

所有的操作事件首先必须执行的是按下操作(ACTIONDOWN)事件,之后所有的事件都是以按下操作作为前提,当按下操作完成后,接下来可能是一段移动(ACTIONMOVE)事件然后抬起(ACTION_UP)事件,或者是按下操作执行完成后没有移动就直接抬起。这一系列的动作在Android中都可以进行控制。

我们知道,所有的事件操作都发生在触摸屏上,而在屏幕上与我们交互的控件都继承于View,所有布局控件继承于ViewGroup(ViewGroup又继承于View)。事件操作主要就是发生在View和ViewGroup之间。

interceptTouchEvent方法用于事件的拦截,Android中所有的事件向下传时都必须经过被这个方法的拦截,然后决定是自身消费当前事件还是继续往下分发给子控件处理。分发逻辑是:返回值为系统默认,事件由dispatchTonchEvent()接收(如果是view,事件会直接传递给onTonchEvent()方法);返回值为true时,ACTION_DOWN事件被dispatchTonchEvent()消费掉,不往下传,而且位置会被记录下来,MOVE、UP也会被dispatchTonchEvent()方法消费掉;返回值为false,事件回传给父布局或activity的onTonchEvent()方法,如果上层的onTonchEvent()也返回false,事件将会消失。

dispatchTonchEvent是ViewGroup中才有的方法,View中没有,因为ViewGroup中可能还有子View。它的作用是负责事件的拦截。返回值为系统默认或false时,事件交给子控件;返回值为true时,事件传递给自己的onTouchEvent()方法,且不往下传。

onTouchEvent()用于事件的处理,返回值如果为系统默认(view为true,viewgroup为false)而且当前控件或布局没有设置onTouch或onClick事件时,事件传递给父布局或activity的onTouchEvent()方法,对应的MOVE、UP事件也会直接被传递给父布局或activity的onTouchEvent()方法里;否则,事件会被当前控件或布局的监听器消费掉;返回值为true时,事件被viewGroup的onTouchEvent()方法消费且对应的MOVE、UP事件将跳过InterceptTonchEvent()方法而直接被onTouchEvent()方法消费。返回值为false时,事件会被返回给父布局或activity的onTouchEvent()方法里。

       


猜你喜欢

转载自blog.csdn.net/ywj_486/article/details/53739152
今日推荐