• android+ onTouchEvent


    非自创,转自http://www.eoeandroid.com/thread-319301-1-1.html

      Android的触摸事件消息传递机制,网上的各种分析、总结很多,有深入源码的,有图文并茂的。你总结他总 结,终归也都是别人的总结,不是我总结。每次匆匆看过,知道个大概,也没仔细琢磨过,总是过一阵就记不清细节了,但这回项目中遇到了相关问题,看来是要下 功夫认认真真深入研究了。

           先奉献上几个不错的资料,真是随手一百度,金银财宝挡不住:
                          http://blog.csdn.net/guitk/article/details/7057155      流程图不错;
                          http://blog.csdn.net/stonecao/article/details/6759189     源码分析,可深入了解内部机制与函数调用过程;
                          http://www.cnblogs.com/xiaoQLu/archive/2013/04/02/2994030.html   这个也不错;
           下面是用自己的话和画来总结的:
           总共涉及到的知识包括:
    • dispatchTouchEvent
    • onInterceptTouchEven
    • onTouchEvent
           这三个函数与ViewGroup、View之间的消息传递(虽然ViewGroup继承于View,但这里为了方便,ViewGroup是布局容器,View是布局内的控件)。
          以及ACTION_DOWN、ACTION_UP、ACTION_MOVE、ACTION_CANCEL这四种消息类型。


          触摸事件是一连串ACTION_DOWN,ACTION_MOVE..MOVE…MOVE、最后ACTION_UP。
          从头说起,先看ACTION_DOWN的处理。
          触摸事件总是先由最下面的ViewGroup先收到,在dispatchTouchEvent 函数中向其子控件派发ACTION_DOWN消息,子控件可能是ViewGroup也可能是View。
           在派发给子控件之前要先调用ViewGroup的onInterceptTouchEvent拦截器,如果消息没有被拦截,则向其子控件派发 ACTION_DOWN消息(至于向哪个子控件派发消息,在dispatchTouchEvent 源码中有命中测试)。如果子控件是ViewGroup,则由它的dispatchTouchEvent 函数再次进行消息派发,重复上面的工作(检查拦截器,命中测试,向命中的子控件派发消息);如果子控件是View,则会由View的 onTouchEvent响应ACTION_DOWN事件。
           如果在ViewGroup的onInterceptTouchEvent拦截器中将消息拦截了,则后续不会再向子控件传递ACTION_DOWN消息了,会直接将消息传递给这个ViewGroup的onTouchEvent进行响应。
           在控件进行onTouchEvent处理过程中,如果控件没有消费这个ACTION_DOWN事件(即返回false,消费这个词翻译过来真别扭,还是 consume感觉顺一点…),则会将ACTION_DOWN传递给其父ViewGroup的onTouchEvent进行处理,直到由哪一层 ViewGroup消费了ACTION_DOWN事件为止。
            如果有哪一个控件的onTouchEvent消费了ACTION_DOWN事件,则后续的n个ACTION_MOVE与1个ACTION_UP都会逐层传递到这个控件的onTouchEvent进行处理。
            这里要注意是逐层,也就是说每层的拦截器还是可以拦截到后续的ACTION_MOVE与ACTION_UP。如果后续的ACTION_MOVE与 ACTION_UP被某层的拦截器拦截,则后续的事件将不会再传递给之前处理onTouchEvent的子控件,而是逐层传递给由拦截消息的这个控件的 onTouchEvent函数进行处理,并且会向其之前接收事件的子控件发送一个ACTION_CANCEL,表示后续事件被取消了。
            如果所有控件的onTouchEvent都没有消费ACTION_DOWN事件,每层dispatchTouchEvent 都会返回false,表示事件没有被派发出去,后续的ACTION_MOVE与ACTION_UP也都不会再被传递了。
            这个就是整个触摸事件消息传递的流程。
           还有一种极端的情况,如果某个控件一开始消费了ACTION_DOWN,可是ACTION_MOVE接连来找它消费的时候,它并不消费 ACTION_MOVE,但是后续的ACTION_MOVE与UP还是会来找它(真是嫁鸡随鸡嫁狗随狗…),只是每层的 dispatchTouchEvent 会返回false,说明事件没被消费。此时如果想让上层ViewGroup接管事件,则必须由该ViewGroup在 onInterceptTouchEvent中进行拦截。
           (ViewGroup真是富二代,层次高地位高,巧取豪夺?!拦截后,它只会给我等下层阶级屌丝一个ACTION_CANCEL说被取消了…还不如叫 ACTION_CANCEL_SO_SORRY_TO_YOU_DIAOSI!!!哈哈,整篇文章都尽量措辞严谨但还是在最后失了节操)。
    1、以专家为榜样,不必自己重新探索
    2、解构技能,找出实现80%效果的那20%
    3、不要一心二用
    4、练习练习再练习!然后获得即时反馈
    5、坚持,不要在低谷期放弃
  • 相关阅读:
    about_并查集
    MST_prim
    MST_kruskal
    物联网的未来:关于物联网的10个预测
    如何展现云计算安全领导力
    虚拟机发展依然强劲,但会被容器取代吗?
    如何从人工智能部署中获取最大价值
    维特根斯坦:为何夸大人工智能是对人性的贬损?
    区块链技术还在不断创新
    区块链真正能用来干什么?这5件事说清楚了
  • 原文地址:https://www.cnblogs.com/zhongyuan/p/4239249.html
Copyright © 2020-2023  润新知