美文网首页
Touch事件分发机制

Touch事件分发机制

作者: Davisxy | 来源:发表于2019-04-02 12:11 被阅读0次

纯属个人理解,不适合别人阅读学习;适合理解的人指出我的一些错误理解和讨论;

一个完整的Touch时间,包括一个down事件,多个move事件,一个up事件,偶尔还会有cancel事件;
Touch事件的一般传递流程Activity->window(唯一实现类PhoneWindow)->顶级View(DecorView)->VIewGroup->View
首先从dispatchTouchEvent中开始分发,中间会碰到onInterceptTouchEvent来判断是否要拦截事件,默认是不拦截;如果拦截的话,会将事件传递给onTouchEvent方法中去处理,如果不拦截,则会将事件继续下发在下级View或者ViewGroup的dispatchTouchEvent中去,这样重复上面的操作,一直到View的dispatchTouchEvent,View是没有拦截方法的,所以直接到了View的onTouchEvent事件中,如果该方法返回true则该事件消耗掉,否则就是将事件往上传给父控件的onTouchEvent中去处理;

在这中间,如果设置了onTouchListener的话,会先执行onTouch方法,如果该方法返回true,就没有了后来的onTouchEvent的事了,只有返回false才有机会;

梳理了代码流程后:
一个Touch事件发出,首先触发Activity的dispatchTouchEvent方法,在内部,如果当前是down事件,则触发屏保方法(onUserInteraction()方法,在触摸home,back,menu时触发),然后调用
return getWindow.superDispatchTouchEvent(ev)
|
return mDecor.superDispatchEvent(ev)
|
return super.dispacthTouchEvent(ev)
mDecor是顶层View,对应着FrameLayout,他的super就是ViewGroup;也就是调用ViewGroup的dispatchTouchEvent方法;

在ViewGroup中,会有一个拦截判断:disallowIntercept||!onInterceptTouchEvent(ev)
如果不拦截就往下走,拦截就跳过这个判断条件;
如果不拦截往下走会遍历ViewGroup的所有子View,找到被点击的那个View,调用child.dispatchTouchEvent;如果返回true,则整体返回true,如果返回false,则跳出拦截开始的这个判断条件,和上面拦截走同一条路;调用super.dispatchTouchEvent方法(ViewGroup的super就是View,也就是调用View的dispatchTouchEvent,注意:这里的View不同于上面的子View,上面的子View是位于ViewGroup上,而这个里的View则是ViewGroup的父类,通过调用父类View的dispatchTouchEvent来间接调用ViewGroup的onTouchEvent方法,其实你会发现在ViewGroup中是没有onTouchEvent这个方法,因为他是继承自View,所以才有了这个方法的使用权,本质上这个onTouchEvent还是父View中的方法)
既然两条路都走到了View中,那就继续View的dispatchTouchEvent

在View的dispatchTouchEvent中,有三个判断条件:
1、onTouchListener不为空
2、View可用enable
3、onTouch返回true
三个都成立的时候:return onTouchEvent(ev);

如果是从ViewGroup拦截过来的,则最终ViewGroup的dispatchTouchEvent返回onTouchEvent同等结果,如果是从child.dispatchTouchEvent过来的则返回onTouchEvent同等结果

这里之前我一直有个问题就是:Touch事件从Activity到ViewGroup再到View,如果一直默认执行则会调用View的onTouchEvent,如果View的onTouchEvent返回false则调用ViewGroup的onTouchEvent,我一直比较好奇是怎么调用到父类的;
这里就可以看出来,当View的onTouchEvent返回false时,就会在ViewGroup的dispatchTouchEvent继续往下走,然后调用了super.dispatchTouchEvent,这样就到了View的dispatchTouchEvent中,就会调用到ViewGroup的onTouchEvent;

这里贴一副我理解的图:


IMG_0418.JPG

当一个事件序列下发时,如果down被View消耗掉,然后ViewGroup拦截了move事件,则这个move事件会变成cancel事件继续下发到消耗down事件的View,而且不会在回传;下一个move事件才会到达ViewGroup的onTouchEvent。

本篇文章完全基于Android事件分发机制详解:史上最全面、最易懂可能是讲解Android事件分发最好的文章所理解的,不太适合别人阅读,如有需求可阅读这两篇。


Android事件分发机制详解:史上最全面、最易懂
可能是讲解Android事件分发最好的文章


相关文章

  • 【Android】事件分发机制

    一、事件分发机制过程 Android事件分发机制是Android开发必须掌握的东西,分发的事件是点击Touch事件...

  • Touch事件分发机制

    touch事件分发机制有3个重要的方法 -dispatchTouchEvent(MotionEvent ev) ...

  • Touch 事件分发机制

    原文:http://xiazdong.me/2015/09/19/touch-dispatch-mechanism...

  • Touch事件分发机制

    纯属个人理解,不适合别人阅读学习;适合理解的人指出我的一些错误理解和讨论; 一个完整的Touch时间,包括一个do...

  • Touch事件分发机制

    最近看到一篇文章,关于touch时间分发机制,这篇文章很通俗易懂的方式让我明白了其中原理。 Touch事件分发中只...

  • UI要点

    事件分发机制及响应者链 事件分发机制 iOS 检测到手指触摸 (Touch) 操作时会将其打包成一个 UIEven...

  • Android基础(28)事件分发

    1)请描述一下View事件传递分发机制2)Touch事件传递流程3)事件分发中的onTouch 和onTouchE...

  • Android Touch事件传递机制

    简介:   Touch事件的传递机制与生活贴近,从父布局开始一步一步的向下分发事件。分发事件时调用boolean ...

  • 事件的处理机制和手势的操作

    事件的处理机制和手势的操作 iOS中的事件分发## 事件的分类### Touch Events(多点触摸事件) 视...

  • Android Touch事件分发机制

    Touch事件相关的方法 1、dispatchTouchEvent(motionEvent:MotionEvent...

网友评论

      本文标题:Touch事件分发机制

      本文链接:https://www.haomeiwen.com/subject/wqvbbqtx.html