View的事件分发机制

View的事件传递机制:
【1】事件分发

View:(如果不是ViewGroup类型,代表没有子View 所以需要将所有结果向爸爸报告)
public boolean dispatchTouchEvent(MotionEvent event) {
官方注解:
将触摸屏运动事件向下传递到目标视图,或者查看它是否为目标。

可以被重写 可以被其他对象调用

返回值代表 当前的View是否处理了这个事件

【1】事件应该首先被辅助性焦点处理,如果我们没有焦点或者没有虚拟的后代有焦点,那么我们应该不去处理这个事件(返回false)
【2】如果上面没有返回false,继续正常的处理流程

如果是ACTION_DOWN操作,停止正在进行的嵌套滚动
筛选触摸事件以应对安全策略,如果这个事件需要被分发那么返回true,否则应该丢弃
当窗口被遮挡的时候,就放弃这个触摸事件(onFilterTouchEventForSecurity),如果onFilterTouchEventForSecurity
返回的是false,那么最后的结果就是false,如果onFilterTouchEventForSecurity返回true,继续走下面的流程

如果当前view是可点的状态,然后当前如果通过鼠标输入控制滚动条拖动将事件作为滚动条拖动处理就是true否则就是false(handleScrollBarDragging),这个时候 返回true

如果可点击且消耗了这个事件 返回true

如果当前事件还没有被处理 然后 被touchevent处理了,返回true

如果当前是 ACTION_UP ACTION_CANCLE 或者 result = false 加上 ACTION_DOWN 那么就定制嵌套滑动

public boolean onTouchEvent(MotionEvent event) {
官方注解:
实现这个方法去处理触摸屏幕运动事件,不建议用来处理点击事件,如果事件被处理返回true,否则false

【1】判断当前的View是否可点
【2】不可点直接返回false
【3】如果委托不是null,然后在touchevent之后返回true,那么就返回true

什么是mTouchDelegate???
【4】如果可点击或者长按悬停有提示…..一系列操作之后,返回true
【1】ACTION_UP:
如果需要处理tooltip,那么就去处理
如果不可点,那么移除各种回调,将各种变量置为false,break

【5】以上都没有返回,最后返回false

ViewGroup:
dispatchTouchEvent
【1】过滤掉不符合安全策略的事件,窗口被遮住之类的
【2】如果当前是 ACTION_DOWN ,那么在开始一个新的触摸手势的时候,扔掉之前所有的状态,framework层由于app的切换,当前程序无响应或者一些其他的状态改变可能已经丢掉了ACTION_UP 或者 ACTION_CANCLE
【3】出现了检查拦截的对象intercepted
【4】当前是ACTION_DOWN而且触摸列表中第一个触摸目标不为null,那么我们先取的 是否允许拦截的对disallowIntercept,如果允许那么我们就调用自身的onInterceptTouchEvent,拿到返回结果赋值给intercepted,然后重新保存action,防止改变;如果不允许,那么就直接给intercepted赋值为false
【5】如果不满足以上条件,直接将intercepted设置为true
【6】如果没有被取消且没有被拦截
【1】如果事件的目标是可访问性焦点,我们将其提供给具有辅助功能焦点的视图,如果不处理它我们清除标志并像往常一样将事件分派给所有子级。我们正在查找以可访问性为中心的主机,以避免说明因为这些事件非常罕见。
【2】ACTION_DOWN
【1】找到一个可以接收事件的子view,遍历子View
【2】将孩子传给dispatchTransformedTouchEvent函数,判断如果当前需要cancle或者旧的动作需要cancle,我们将这个cancle设置给event,如果孩子是空的那么就调用父类View的dispatchTouchEvent,否则就调用孩子的dispatchTouchEvent
【1】将孩子或者自己调用View的dispatchTouchEvent结果返回
【3】如果返回结果是true也就是说已经被处理了,那么就跳出循环
【7】触摸列表中第一个触摸目标为null,就调用自己的函数dispatchTransformedTouchEvent,将参数child传为null,这样就是自己调用父类的dispatchTouchEvent方法
【8】不为null,从mFirstTouchTarget开始向后遍历,那么还是调用每个孩子的dispatchTouchEvent方法,如果有一个孩子处理过了,那么就直接复制为true

onInterceptTouchEvent
onTouchEvent

其实如果mIntercepted就是控制了是由viewgroup自己处理还是交给孩子

你可能感兴趣的:(View的事件分发机制)