前言:scrollview是一个很常用的组件,如排行榜,背包,关卡选择页面等等。如果里面的item简单数量少还好,一旦复杂而且数量多,那么drawcall就会非常高。然后就搞了这个循环+分帧+分层滑动面板
原理
循环列表:只创建视图范围内行数+1的数量item,当item滑动到超出视图顶部时,将item移动到底部。反之,当item滑动到超出视图底部时,将item移动到顶部。循环利用超出视图的item,能极大优化item数量很多而引发的性能问题。
分帧加载:当item比较复杂时,一次性创建N个item可能会造成短暂的卡顿,在创建item前获取当前时间,创建item后获取当前时间,创建后减去创建前所获取的时间,就是创建item所需时间,如果所需时间大于某个值,就先不要创建,弄个计时器,延迟一会再创建,延迟期间先执行其他游戏逻辑
分层渲染:因为合批是按照深度遍历合批的,导致虽然item样式一样,但却没法合批。创建item时,把所有子节点分离出来与item同一父节点,然后通过设置zIndex改变层级从而合批**(注:因为label如果用系统字,并且CacheMode为None时,是无法合批的,所以如果检测是默认字体并且Cache Mode为None时,会将CacheMode改成BitMap或者Char才能合批,如果item里的label只有数字考虑用char,如果带各种中文,用BitMap)**。
优缺点
优点:大幅度降低drawcall,加上只实例化视图范围内+1的行数,对于item数量极大的来说,能有效降低开销。
缺点:因为和item是同一父节点,item子节点的active属性用来同步父节点的active属性了,所以不能使用active属性来修改item子节点的显隐,用了会出问题。如果要改item子节点的显隐,请用opacity。
如上图,左下角信息drawcall占1个,空的滑动面板占4个(不知道为啥一个空mask占用4个drawcall,据说是统计策略问题),item背景1个,label1个,共7drawcall。
数据200个,实际上item只实例化35个,无论数据多少个,item始终只实例化视图窗口数量+1行的数量。
注:目前的组件只是简单的功能实现,常规的竖向布局。如果item有非常复杂的功能,例如比例大小变化之类的,横向的,目前这个组件都不支持。
附demoScrollView.zip (205.0 KB)
引擎版本:2.2.2