前言
和匹配侧的各位同学一起维护动态item已经有一段时间了,一开始接触感觉这个东西很高深莫测,随着接触时间的增加,相关业务开发的处理,算是对动态item整个渲染过程有一些理解.在这里写一篇日志记录一下.
动态item以更加快速的构建用户ui视图,可以降低app发版诉求甚至在一些场景下可以免于app发版.
其中快速构建视图是通过动态item提前将描述ui视图结构通过描述性语言事先存放,在渲染阶段通过读取描述性的json文件,使用事先规定好的规则将视图渲染上屏.
让app免于发版是通过将描述文件放置到服务端,通过app冷启动接口下发,这样可以做到增量更新,一些新的需求发布之后,只需修改描述文件中的某一项,不需要改动到native代码,即可完成视图的渲染,降低了发版次数.
渲染流程–流程图
因为动态item存在这样的特性,相较于一般的ui层渲染,他需要多一个配置文件. 整个渲染流程图如下
渲染流程–配置文件
在业务中中动态item主要用于列表的渲染,下面就以列表卡片为例概述下整个流程,因为卡片样式改动较小,并且交互较低.所以一次配置文件完成后,可以较长时间内不在变动.
对于一个列表卡片,渲染流程中主要关注tableview的两个代理方法一个是cellforrow方法,一个是heighforrow方法.其中cellforrow方法需要返回一个卡片,在这个方法内就可以按需进行ui的搭建.
动态item的ui搭建使用从上到下从做到右的顺序进行每一行作为一个容器,整个卡片又作为一个更大的容器,因此,在内部可以实现递归的UI搭建:以其中一条数据搭建为例:
1 | { |
渲染流程–ui
这是一个”item“,其中的“key”值,对应从接口取数据的”key“值.“data”是一个数组,表示内部可以容纳多个”item“,”rowstyle“用来描绘该容器的位置 “rowType”描绘该容器的类型,比如是否嵌套等.
”widgetType“ 标识当前视图的类型,可能是view,label,button,image等. 因此对于每一个item,都可以按照类似的方式设置其内部的视图,默认内部视图是从左到右排列的,有了这个实例,可以看到,data内的每一个元素可以做很多的扩展,比如想添加borderline,添加富文本等,都可以新增一个key值去加以标识.最后值的渲染只需要保证前后端约定的”key”的内容一致即可.
cellforrow对数据源做了处理,也约定了卡片某个容器的位置,但是容器需要多大,最终整个卡片需要多高是需要通过heightforrow去处理的.
item中只指定了每个容器和容器内部每个视图间的间隔,因此容器大小和容器内每个视图的大小都需要根据内容进行处理. heightforrow 就是需要统计内部视图最终的高度来得到cell的高度.
渲染流程–上屏展示
当卡片的高度确定,卡片内的内容确定之后就可以通过数据源赋值然后上屏展示了.在页面的滑动过程中,因为会存在cell的复用机制,但是在业务上每个卡片的高度是不统一的,卡片的重用也是通过模版内的一个字段加以控制,就算是字段名相同,业务接口返回的数据也可能缺少某些条目导致卡片高度不同,因此在性能上会造成一定的损耗,不过这也是业务不断变化导致的不可控制的结果.理想情况下动态item创建的卡片应该变化很小,但是业务却不断往卡片中增加内容,导致规范性降低.
思考和感悟
动态item是为了快速搭建ui和解决因业务迭代带来的app发版频次问题,在满帮主要应用在列表卡片上.但是由于以往的ui不规范,加上一开始时间紧迫导致设计的不完整,对于当前的迭代已经显得疲软了.但是动态item的思路是很不错的,他增加了一个配置文件,通过这个桥梁将一些依靠native代码的东西方法哦服务端接口.对于变动不大并且交互较少的视图是很有用的.并且可以在当前能力的基础上在扩展很多其他的能力.