美文网首页
关于CoordinatorLayout.behavior 学习

关于CoordinatorLayout.behavior 学习

作者: SoLix | 来源:发表于2017-02-22 18:25 被阅读0次


    我在微信公众号中开间别人推荐的第三方库,看到这枚一个库:该库可以帮你快速实现TabLayout和CoordinatorLayout的组合效果。效果如下:

    图1

    Github地址:https://github.com/hugeterry/CoordinatorTabLayout

           看到这个库我就想在自己的demo中试一下,看到介绍是使用CoordinatorLayout 实现的我就在网上搜了文章看看,之后看到别人的总结(附上链接http://blog.csdn.net/huachao1001/article/details/51554608),是关于 CoordinatorLayout.Behavior的使用,效果图不好弄出来,就简单说一下:就是在CoordinatorLayout布局中拖动一个button 另一个button随之移动,这个感觉很好实现,但是耦合会很大,上面的链接中就介绍了用CoordinatorLayout.Behavior怎么实现,先去看完上面的链接讲解再回来看接下的内容。

           最后我有个疑问就是:button 添加了app:layout_behavior="com.hc.studyCoordinatorLayout.MyBehavior"之后怎么跟着tempView随之移动的,tempView 中没有添加任何的监听等多余的代码???但是效果真的出来了,跟着这个疑问我就点开了CoordinatorLayout.Behavior的源码看看是怎么实现的:在MyBehavior这个类中有这个方法layoutDependsOn,只有这个方法与tempView有关联,我们来看下你父类中对这个方法的解释:

    /**

    * Determine whether the supplied child view has another specific sibling view as a

    * layout dependency.

    *

    This method will be called at least once in response to a layout request. If it

    * returns true for a given child and dependency view pair, the parent CoordinatorLayout

    * will:

    *

    Always lay out this child after the dependent child is laid out, regardless

    * of child order.

    *

    Call {@link #onDependentViewChanged} when the dependency view's layout or

    * position changes.

    *

    * @param parent the parent view of the given child

    * @param child the child view to test

    * @param dependency the proposed dependency of child

    * @return true if child's layout depends on the proposed dependency's layout,

    * false otherwise

    * @see #onDependentViewChanged(CoordinatorLayout, android.view.View, android.view.View)

    */

    public boolean layoutDependsOn(CoordinatorLayout parent, V child, View dependency) {

    return false;

    }

    意思是:确定提供子视图还有另一个特定的兄弟视图布局的依赖。

    此方法将响应布局请求至少调用一次。 如果它

    对给定的子视图和依赖视图对返回true,父CoordinatorLayout将:

    总是把这个孩子依赖孩子,不管孩子的秩序。

    当依赖布局位置大小改变的时候调用;

    /**

    * Check if an associated child view depends on another child view of the CoordinatorLayout.

    *

    * @param parent the parent CoordinatorLayout

    * @param child the child to check

    * @param dependency the proposed dependency to check

    * @return true if child depends on dependency

    */

    boolean dependsOn(CoordinatorLayout parent, View child, View dependency) {

    return dependency == mAnchorDirectChild

    || (mBehavior != null && mBehavior.layoutDependsOn(parent, child, dependency));

    }

    在CoordinatorLayout布局中检查子视图依赖另一个子视图;

    /**

    * Check if the given child has any layout dependencies on other child views.

    */

    boolean hasDependencies(View child) {

    final LayoutParams lp = (LayoutParams) child.getLayoutParams();

    if (lp.mAnchorView != null) {

    return true;

    }

    final int childCount = getChildCount();

    for (int i = 0; i < childCount; i++) {

    final View other = getChildAt(i);

    if (other == child) {

    continue;

    }

    if (lp.dependsOn(this, child, other)) {

    return true;

    }

    }

    return false;

    }

    就是循环查看子视图依赖另一个子视图;在上面的源码中我们可以知道通过循环来检查视图的依赖关系;

    好到这里我们就可以总结一下它的实现原理了:

            首先我们自定义的MyBehavior 继承了CoordinatorLayout.Behavior类,并重写这个抽象类的两个方法layoutDependsOn和onDependentViewChanged,layoutDependsOn是判断CoordinatorLayout下的子视图是否其中一个子视图依赖另一个子视图,onDependentViewChanged 是当被依赖的子视图发生改变了都会执行这个方法。

            我们从layoutDependsOn看起,找到CoordinatorLayout.Behavior 中的layoutDependsOn方法,在整个类中查找哪里调用了layoutDependsOn方法,这个调用过程是:onMeasure方法第二行调用了ensurePreDrawListener方法,ensurePreDrawListener方法里通过循环遍历CoordinatorLayout的每个子视图并调用hasDependencies方法来判断CoordinatorLayout下的子视图是否有依赖关系的,如果有在ensurePreDrawListener中调用addPreDrawLinstener方法添加依赖监听,在addPreDrawLinstener方法中给ViewTreeObserver添加监听(创建的OnPreDrawLintener),OnPreDrawLintener这个类实现ViewTreeObserver.OnpreDrawListener接口,并在实现的onPredraw方法中调用DispatchOnDepentViewChanged方法,DispatchOnDepentViewChanged这个方法就是前面说的CoordinatorLayout.Behavior中的一个方法用于当被依赖的子视图发生改变了都会执行这个方法;

             看到这里我们就对CoordinatorLayout.Behavior有了一个大致的了解之后我们就可以用CoordinatorLayout.Behavior写一下想要的效果了。

            我这理解的很浅,只是一些表面上的理解,这是我学习之路上的一部分,我会坚持把我学习到的东西总结下来希望对大家起到些作用。

    下面粘贴一下源码:

    图2 图3 图4 图5 图6

    相关文章

      网友评论

          本文标题:关于CoordinatorLayout.behavior 学习

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