Cocos2d lua 之 ScrollView重用item

1.做了什么

问题:

在使用ListView的时候,有多少个数据就会创建多少个item,并不会重复利用或回收释放。
随着数据量的增加,会对性能造成很大的影响。

解决方案:
  • clone 改成 create[据说是这样,我没有测试过 = =…]
    我们在使用ListView的时候,创建一个item,是通过lua重写的pushBackCustomItemView,
    它会先调用ListView的pushBackDefaultItem,通过clone创建一个csb,我们再把数据赋过去。
    所以,我们完全可以create一个csb,相对于clone会快一些。

    缺点: 这个应该会有点效果,嗯,有点效果而已。

  • 分帧加载(逐帧加载)
    并不是在一帧全加载完,而是选择每帧加载一定个数,直到加载完成

    缺点: 通过lua现有的协程来实现,但是流畅度不是很好,刚进入界面的时候可能看到item是逐渐加载进来的。

  • 异步加载
    这个主要对一些图片多的item,我们如果需要切换图,可以通过异步加载,等图片加载完再换图,这样不影响之后item的加载。

    缺点: 会看到 默认图(csb创建的样子) -> 真正效果的转换过程。

  • 滑动到底加载
    就是先加载一定数量,监听到底部了,再拉取后面的部分,直到全部加载完。

    缺点: 做一系列监听滑动等,没有根本解决问题。

  • 重用item[本次实现的方法]
    其实,上面的那些方法,都是优化的技巧,并没有从根本上解决问题。
    我们要根本的解决问题,就是创建可视区域可容纳数量+1的item,然后不断重用这些item。
    在ListView同一时刻,只能见到5个item,那我就创建6个item,然后不断重用这些item。




2.怎么做的

机制

首先明确view与inner,
view像一个窗口,它的大小就是我们可以见到的大小(当然要设置裁切),
inner是我们创建的所有item添加的地方(item并不是加载ScrollView上,而是加在了inner上)
ScrollView/ListView会监听滑动,同时相应的移动inner的位置,从而让我们看到item位置的变化。
简而言之,item加载inner上,是inner动,不是view动。

想法

在ScrollView或者ListView中,正常情况是这样的:
(前面数字代表item位置,后面数字代表item, ~~~~代表可视区域)

1   1                   1
    ~~~~
2   2                   2
3   3                   3
                        ~~~~
4   4                   4
    ~~~~                
5   5                   5
6   6                   6
                        ~~~~
7   7                   7
8   8                   8

可以发现,
前面的例子中, 只能看见2, 3, 4; 但是看不见的1, 5, 6, 7, 8 依旧存在
后面的例子中, 只能看见4, 5, 6; 但是看不见的1, 2, 3, 7, 8 依旧存在

所以,我们改成下面的样子:

1                        
    ~~~~
2   2                    
3   3                    
                        ~~~~
4   4                   4
    ~~~~                
5                       5
6                       6
                        ~~~~
7                        
8                        

因为可视区域只有3个item,我们就创建3个item,然后不断重用它们。(当然实际操作中,需要多创建一个,否则有穿帮风险)
但是,位置,我们依旧留着(划重点,* inner大小不变 *,否则无法滑动),
在往下滑的时候,最上面的跑到下面去顶替下面的item;
往上滑的时候,最下面的跑到上面去顶替上面的item;

做法

实现方法,
可以通过监听ScrollView滑动,每当ScrollView滚动,我们可以知道当前inner位置,
然后知道item的位置,从而判断item需不需要移动位置。
这里,用的是编辑一个绘制方法,每隔一段时间,都看一下各个item位置,然后根据需求移动位置。
我们在加载csb的时候将ScrollView记录下来,在view的update中调用它。
(本来想重写update,但是遇到了一些问题,所以妥协用了它,具体可以看后面 遇到的问题)

init:
    --[[
        name            :   item类名 
        totalItemNum    :   item总数
        ...             :   创建item时需要的参数
    --]]
    function ScrollView:setItemViewModel(name, totalItemNum, ...)

    主要代码:
        -- 得到所需绘制item个数
        local count = math.ceil(self:getContentSize().height / self.tItemContentSize.height) + 1
        for i = 1, count do
            -- 创建item
            local view = CSBReaderLoad(name)
            view:init(...)
            if view.setIndex then
                view:setIndex(i)
            end

      
  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值