尽管名字是CoordinatorLayout系列,但博主并不知道这个系列最终会有几篇文章。(逃
最近博主由于项目原因研究了一下android.support.design.widget包中的CoordinatorLayout。这篇文章从源码上简单分析一下这个控件的实现。
一句话总结,这个控件的特点是能够协调子view的行为。
比如下图。
#那张scrolling-view# --> gif太大传不上来
其实这张图是系统默认的一个实例activity。你只要在创建一个android项目的时候选择左下角的scrolling activity。运行一下就是上图的效果。
生成的activity_scrolling的布局。
尽管上面有很多陌生的控件比如CoordinatorLayout,AppBarLayout,CollapsingToolbarLayout,NestedScrollView,
FloatingActionButton,但其实它的直接子节点只有三个。即下图。
如果将重点放在这三个子view上,那么这个gif图上值得注意的点有
1 三个控件的布局位置控制。比如NestedScrollView在AppBarLayout下面,FloatingActionButton的位置。
2 NestedScrollView向上滑动的时候,AppBarLayout和FloatingActionButton会有联动效果。
3 AppBarLayout内部的字体变化及FloatingActionButton的行为不由CoordinatorLayout负责,而是由AppBarLayout及其内部的CollapsingToolbarLayout的标志共同控制。
好了,大致了解了coordinatorLayout可以做的事之后。下面分析它的实现。
看下类图。
观察类图可以得到的结论有:
1 coordinatorLayout实现了onMeasure,onLayout,onDraw,onInterceptTouchEvent等一个容器控件必须的几个函数。同时还实现了parseBehavior,getDependencies,dispachDependentViewsChanged等调度控制内部view的功能函数。
2 注意到Behavior类。同样实现了layoutDependsOn,onDependentViewChanged,onInterceptTouchEvent等函数。可以合理推测Behavior就是一个代理类,代理子view的包括显示滑动触摸等一系列事件。
接下来看下源码实现。
首先是onLayout的实现。
这里会分别关注AppBarLayout NestedScrollView FloatingActionButton。
首先它会去尝试拿一下子view的behavior。如果behaviour不为空,那么就由该behaviour负责layout的实现。#这种情况对应的是NestedScrollView。#否则调用成员函数onLayoutChild。
onLayoutChild会先判断是否由anchor。#这种情况对应的是FloatingActionButton#。否则会调用layoutChild。
layoutChild对应的就是AppBarLayout。规则很简单根据child的gravity来控制控件在容器中的位置。
一个测试。
总结一下
1 CoordinatorLayout的一般规则就是根据layout_gravity来控制位置。
2 若子view有app:layout_behavior属性,由该属性来控制位置。至于具体怎么控制,由后面的文章进行分析。
3 若子view有app:layout_anchor属性,由该属性来控制位置。至于具体怎么控制,由后面的文章进行分析。
最后看下联动滑动的效果是怎么实现的。
其实很简单。联动滑动一定是从内向外的,就是事件发起一定是从CoordinatorLayout的子view开始,然后通知coordinatorLayout我有一个滑动行为,你要不要进行处理,如果要,那么就联动其他兄弟view进行联动。
看下调用链。
NestedScrollView.onInterceptTouchEvent —> NestedScrollView.startNestedScroll —>
NestedScrollingChildHelper.startNestedScroll —>
ViewParentCompat.onStartNestedScroll —>
NestedScrollingParent.onStartNestedScroll —>
CoordinatorLayout.onStartNestdScroll //到这一步 自然是通知其他子view进行对应的处理了
ok~ 第一篇文章先到这里。