美文网首页
Android自定义事件分发顺序实现思路

Android自定义事件分发顺序实现思路

作者: Hsicen | 来源:发表于2019-10-24 08:36 被阅读0次

事件分发机制大家应该都熟记于心,默认事件分发是逆序的,有哪些方法可以修改分发顺序

修改事件分发顺序的话,在日常开发中基本遇不到,因为现在的逆序遍历,是跟View的层级显示相匹配的,随便更改反而不太合理。

如果非要修改这个顺序,很多同学首先会想到:重写dispatchTouchEvent()方法,然后在里面一个for循环,从0开始一个个调用子View的dispatchTouchEvent()。

这个方法,不是说绝对不行,只是你要做的事情很多,就比如触摸坐标的转换

我们都知道,View Group在分派事件的时候,会检查子View是否应用过属性动画的(位移、缩放、旋转等),如果有的话还要把坐标给映射回去。接着,还会把相对于这个View Group本身的触摸坐标 转换成 相对于对应子View的触摸坐标。

这样说可能有点绕,
举个例子,比如:当手指在屏幕中按下,ViewGroup中收到的event坐标(getX,getY)假设是【500,500】,刚好在这个位置上有个子View,那接下来肯定会把事件传给这个子View的dispatchTouchEvent,这时候如果坐标不转换直接传的话,那子View收到的event坐标(getX,getY)也是【500,500】,这明显是不对的,正确的坐标应该要分别减去它的left和top。

这看起来好像没什么大的影响,但如果你的子View没有重写onTouchEvent方法的话(比如子View是常用的ImageView,TextView之类的),你的OnClickListener就会无效了,因为默认的onTouchEvent在处理ACTION_MOVE的时候,会检查event的坐标是否已经脱离了View的边界范围,如果在边界范围之外的话,pressed将会失效(认为没有被按下),当ACTION_UP时,如果pressed为false,就不会执行PerformClick。

那难道没有方法可以完美地做到了吗?
在ViewGroup的dispatchTouchEvent方法中,虽然它是逆序的for,但是呢,它把子View拿出来的时候,却不是直接操作的mChildren数组,而是通过一个getAndVerifyPreorderedView方法来获得,这个方法会把当前索引传进去,还有一个preorderedList。如果传进去的preorderedList不为空,那么就会直接从它里面去取。

preorderedList怎么来?
通过调用buildOrderedChildList方法获取的。

buildOrderedChildList方法是怎么样的?
它里面是通过一个getAndVerifyPreorderedIndex方法来获取对应的子View索引,这个方法要传进去一个叫customOrder的boolean值。这个customOrder,看名字可以知道,是自定义顺序的意思,如果它为true的话,接着会通过getChildDrawingOrder(int childCount, int i)方法来获取对应的索引,而且,这个方法是protected的,所以我们可以通过重写这个方法并根据参数"i"来决定返回哪一个View所对应的索引,从而改变分发的顺序。

那这个customOrder,什么时候为true呢?
在buildOrderedChildList方法里可以看到这么一句:

final boolean customOrder = isChildrenDrawingOrderEnabled();

emmmm,也就是说,如果要自定义这个顺序的话,还需要调用setChildrenDrawingOrderEnabled(true)来开启。

重新捋一捋流程

  1. setChildrenDrawingOrderEnabled(true)来开启自定义顺序
  2. 重写getChildDrawingOrder方法来决定什么时候要返回哪个子View

使用场景

常用的SwipeRefreshLayout、ViewPager、RecyclerView都实现getChildDrawingOrder方法。其中RecyclerView还可以通过一个setChildDrawingOrderCallback方法来动态指定顺序,而不用重写RecyclerView。

相关文章

  • Android自定义事件分发顺序实现思路

    事件分发机制大家应该都熟记于心,默认事件分发是逆序的,有哪些方法可以修改分发顺序? 修改事件分发顺序的话,在日常开...

  • Android 事件分发机制

    事件分发机制在android中非常常见,比如:手势滑动,自定义View,多点触控都有它的身影。事件分发的顺序是:A...

  • ViewGroup事件分发机制源码分析

    事件分发顺序 Android中的事件处理一直是Android自定义控件开发中的重难点,想写出交互多点的控件处理好触...

  • View事件机制分析

    目录介绍 01.Android中事件分发顺序1.1 事件分发的对象是谁1.2 事件分发的本质1.3 事件在哪些对象...

  • 事件分发机制

    XSize的主页 android事件分发的理解: 本文知识点: 理解事件分发的流程; 知道事件分发的调用顺序; 相...

  • View事件机制源码分析

    目录介绍 01.Android中事件分发顺序 02.Activity的事件分发机制2.1 源码分析2.2 点击事件...

  • 事件分发机制

    Android中事件分发顺序:Activity(Window) -> ViewGroup -> View View...

  • Android事件分发机制

    Android事件分发机制,是Android开发中的重点及难点,掌握事件分发机制,可以更好地解决自定义控件、vie...

  • Android ViewGroup事件分发机制源码解读

    分析了关于View的事件分发后,链接是Android View事件分发,分析ViewGroup事件分发自定义一个V...

  • Android事件分发之流程分析,看完你就懂了

    默认的事件分发流程 Android 事件分发的正常流程,也就是默认情况下事件是如何分发的,首先自定义 ViewGr...

网友评论

      本文标题:Android自定义事件分发顺序实现思路

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