美文网首页Android知识Android技术知识Android开发
Android进阶-view 的事件分发机制

Android进阶-view 的事件分发机制

作者: zone7_ | 来源:发表于2017-05-31 18:13 被阅读45次

    在前面的文章中有一系列的自定义 view 的文章,
    Android自定义View-水波纹progressbar
    Android自定义View-刮刮卡效果
    Android自定义View-蜘蛛网属性图(五边形图)
    Android自定义View- 雷达扫描图
    为了更好地学习自定义 view,有必要学习事件分发机制, 这也是 Android 面试中经常会被问到的。
    事件分发机制相关的方法有三个,分别是:

    dispatchTouchEvent(MotionEvent event);
    用于进行事件的分发。如果事件能够传递给当前 view,那么此方法一定会被调用,返回结果受到当前 view 的 onTouchEvent() 和下级 view 的dispatchTouchEvent() 方法的影响,表示是否消耗当前事件。

    onInterceptTouchEvent(MotionEvent event);
    在 dispatchTouchEvent() 内部调用,由来判断是否拦截某个事件,如果某个 view 拦截了某个事件,则一般情况下不会继续往下传递了,此方法也不会再次被调用了。返回 true 表示拦截事件,进一步交由 onTouchEvent() 处理,返回 false 表示不拦截当前事件。

    onTouchEvent(MotionEvent event);
    在 dispatchTouchEvent() 内部调用,由于处理点击事件,返回 true 表示消耗这个事件,返回 false 表示不消耗这个事件。

    文字总是枯燥的,先来看看大图。

    事件分发

    这里描述了一个点击事件的过程,那么现在来解释一下这张图:

    1. 一个点击事件发生之后,事件是现传给 Activity ,Activity 再传递给 Window ,Window 传递给 Top View,然后就是按照事件分发机制去进行。
    2. 如果一个 view 的 onTouchEvent() 返回 false ,则这个事件会传递给它的上一级处理,如果一直返回false ,最终会传递到 Activity 的 onTouchEvent() 进行处理。
    3. 一般情况下,一个事件只能被一个 view 消耗。当然,如果是某个 view 消耗了事件之后,又在 onTouchEvent() 中手动分发,这样就是另外一回事了。
    4. ViewGroup 默认不连接任何事件,ViewGroup 的 onInterceptTouchEvent() 默认返回 false 。
    5. view 默认没有 onInterceptTouchEvent() ,一但事件传递给它,就会调用 onTouchEvent() 。
    6. view 的 onTouchEvent() 默认都会消耗事件,除非是不可点击的(clickable 和 longclickable 同时为 false。
    7. 有些控件默认 clickable 为 true,例如 Button。有些默认为 false,例如 TextView。所以在设置点击事件的时候就要注意,有些时候不能设置点击事件,可能是因为这个。
    8. 子元素可以通过 requestDisallowInterceptTouchEvent() 干预父元素的事件分发。

    参考文献:《Android开发艺术探索》

    我的公众号

    公众号内容描述

    zone7 公众号,与您一起学习分享后端知识。本公众号涉及的知识点将会有:nodejs,python,docker,kubernetes,后端架构等


    zone7

    相关文章

      网友评论

        本文标题:Android进阶-view 的事件分发机制

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