前言
上篇我们介绍了Tangram是什么,以及它使用到两个子框架Vlayout和VirtualView。本篇主要整体上来介绍Tangram的组成部分,以及各部分的作用。本篇不涉及原代码,后面,会单独文章对Tangram整体架构、Vlayout、VirtualView代码进行分析。因为VLayout的是基于RecyclerView实现的,最后会整体上对RecyclerView的绘制流程进行介绍。
Tangram适用场景
Tangram可适用于电商首页、内容推荐页等类型的页面,具有以下特点:
- 上下滑动的页面。
- 页面内容变化较频繁,支持个性化展示。例如:电商类首页根据不同的买家推荐不同的商品,展示样式不同。
- 页面整体布局风格,不会频繁的变动。由于布局能力是基于定义好的模板,如果每次都要开发人员开发新的模板,就失去了框架的意义 。
以千千音乐首页为例:
Tangram设计思想
根据上图我们先统一两个概念:
布局:从业务看,一个红框是一组同类型的内容。从技术上看,一个红框就是一个布局。本文中提到的“红框”可以等同布局理解。
组件:从业务看,一个绿框是一个业务内容单元展示,从技术上看,一个绿框就是一个组件,对应就是RecyclerView的一个item。
Tangram设计思想:
- 布局动态化,如上图中,各类型的红框的展示顺序,红框的展示样式,红框的title布局样式都是可以通过服务端下发动态调整的。布局能力的模板是内置在框架里的。
- 组件动态化,如上图中,各类型绿框具体展示的样式,绿框展示业务内容等是可以通过服务端下发动态调整的。组件展示样式的模板可以内置在框架中,也可以动态下发。
- 动态能力粗粒度化,通过布局+组件的形式搭建整个页面,这个动态能力比较粗,不像H5或者Weex从基本的UI元素开始搭建整个页面。
- 组件的复用,如上图中,组件是在不同的布局中的,但是列表类型的页面我们仍然需要实现组件的复用,就像ListView、RecyclerView那样。
Tangram的主要模块的作用
Vlayout-------实现布局动态化
Vlayout本身是一个单独的框架,是对RecyclerView的布局能力的加强版,提供了支持上图中不同布局样式的布局能力。一个布局会有一个LayoutHelper类去负责完成布局能力的实现。
VirtualView-------实现组件动态化
VirtualView本身是一个单独的框架,提供一套自定义View,和一般View一样可以在布局页面时使用。并且提供了View的动态化和虚拟化,虚拟化是可以简单理解为页面绘制渲染是简化View树来优化性能的。动态化,是指一个或者一组View,可以通过服务端下发给客户端去动态展示,而这里说的一个或者一组View,就可以理解为Tangram的一个组件的。也就是Tangram是使用VirtualView实现了组件的动态化。
Tangram核心框架-------实现业务数据和动态布局的结合
Tangram核心框架实现整个框架的初始化、流程控制、业务数据和动态布局的组合等功能。其实可以简单理解为,就是对Vlayout和VirtualView的完整的封装。
RecyclerView绘制流程
RecyclerView的组成部分
- LayoutManager 负责RecyclerView子View的布局过程,常用的有LinearLayoutManager(线性布局),还有GridLayoutManager(网格布局)和StaggeredGridLayoutManager(瀑布布局)等。
- Adapter 负责将数据转变成视图,使用时需要继承该类。
- ItemAnimator 收集并执行子视图动画,RecyclerView有默认的子视图动画,也可自定义实现。
-
ItemDecoration 分隔线,需自定义实现。
Tangram使用了RecyclerView的布局能力,这里我们着重分析他的绘制流程。
RecyclerView的绘制流程
RecyclerView自定义的ViewGroup,绘制流程肯定还是基于原生流程的onMeasure、layout、draw三大绘制流程,但是基于这三大流程进行了功能扩展。
测量和布局流程
需要强调一点的是,RecyclerView是一个布局比较复杂的View,绘制流程已经打破了onMeasure负责测量,layout负责布局的明显划分。而是根据功能需要封装了一下三个布局步骤:
- dispatchLayoutStep1,预布局处理Adapter更新,保存ItemView的动画信息。例如:做一个删除itemview动画时,我首先要ItemView和他的动画保存下来。
- dispatchLayoutStep2,真正itemview的测量和布局,调用了LayoutManager的onLayoutChildren方法,这个方法里面进行对itemView的测量和布局
- dispatchLayoutStep3,执行在dispatchLayoutStep1方法里面保存的动画信息。
为什么说绘制流程打破了onMeasure负责测量,layout负责布局的流程划分?例如在RecyclerView的一般绘制流程中,dispatchLayoutStep2会在onMeasure调用,已经就完成了itemview的测量和布局流程。
那这三个布局步骤的调用流程是怎么控制的?首先三个布局流程还是基于onMeasure、layout中调用,不过调用流程是根据RecyclerView的当前状态决定调用哪一步,RecyclerView有三种状态,来控制三个布局步骤的调用时机。
绘制流程
draw流程相对简单,就是根据需要完成对应的内容绘制,主要做了四件事:
- 绘制ItemDecoration的onDraw部分;
- 绘制itemView;
- 绘制ItemDecoration的drawOver部分;
- 根据mClipToPadding的值来判断是否进行特殊绘制。
LayoutManager完成itemview的布局流程
- 计算布局锚点所在位置。
- remove掉RecyclerView的itemView。
- 根据锚点信息,循环调用fill方法进行itemView的填充。
fill方法就是RecyclerView的完成itemview布局的地方,而Vlayout就是以这个里为切入点,自定义了LayoutManager将布局能力委托给了LayoutHelper完成。也就是,我们想自己定义一种特定的布局样式,就是要自定义一个LayoutHelper。
RecyclerView的绘制流程补充
以上说的流程是一般流程,实际流程要复杂很多,这里给大家补充说明一点:对于一个绘制完的RecyclerView,屏幕上的itemView不是每次都全部remove再添加的。例如滑动时候,并没有调用到onLayoutChildren,而是通过调用itemview的offsetTopAndBottom方法实现滑动。 但是当有新的itemview滑出时,onLayoutChildren会被调用,remove所有的itemView,fill方法进行itemView的填充。
总结
本文主要整体介绍了Tangram三大组成部分以及其作用,RecyclerView的绘制流程。都是结论性的总结说明,为之后的各模块的详细分析,提供一个概念的说明,有利于大家整体上把握Tangram框架。如有理解不当之处欢迎指正。