cocos2d-x lua开发笔记:ListView加载多个item优化处理 (转)

in 编程
关注公众号【好便宜】( ID:haopianyi222 ),领红包啦~
阿里云,国内最大的云服务商,注册就送数千元优惠券:https://t.cn/AiQe5A0g
腾讯云,良心云,价格优惠: https://t.cn/AieHwwKl
搬瓦工,CN2 GIA 优质线路,搭梯子、海外建站推荐: https://t.cn/AieHwfX9

转自[sinat_24556247的博客]
coco2d-x开发过程中,用过ListView的都知道,ListView是一次性将所有的item加载出来的,所以在加载数量较多的item的时候,后导致界面卡顿的现象。其实改用tableView就是解决这一问题,但是tableView的使用却完全不如listView成熟,所以我这里主要是将listView进行优化处理,我使用的是coco3.5 版本,在lua下开发的。

具体的思路是,比如要加载100个item,首先先用常规方法创建100个空widget到ListView上。然后创建屏幕上能显示下的item的最大个数加1(比如说10个),按顺序加载到widget。之后监听ListView的滚动事件,判断当前要显示的10个item是在哪几个widget,然后将其从原来的widget上删除,加到新的widget 上即可。

下面的具体代码,写的不是很好,仅供参考!

修改cocos/framework/extends/UIListView.lua 添加一下代码

function ListView:tableShow(number, grid, callback, refresh)--参数说明 数量,模板temp,刷新回调,强制刷新
    if number == nil or grid == nil or callback == nil then
        return 
    end

    self:onScroll(nil)
    self:removeAllItems()
    if number == 0 then
        self:jumpToTop()
        return 
    end

    self.allItems = self.allItems or {}
    if refresh then
        for _, v in pairs(self.allItems) do 
            v:release()
        end

        self.allItems = {}
    end

    local gridSize = grid:getBoundingBox()
    local innerSize = self:getInnerContainerSize()
    local size = self:getContentSize()
    local direction = self:getDirection()
    local offset = self:getItemsMargin()
    local showNum = 0

    if direction == cc.SCROLLVIEW_DIRECTION_HORIZONTAL then
        offset = offset + gridSize.width
        showNum = math.ceil(size.width / offset) + 2
    elseif direction == cc.SCROLLVIEW_DIRECTION_VERTICAL then
        offset = offset + gridSize.height    
        showNum = math.ceil(size.height / offset) + 2
    else
        return
    end

    local function sortItems()
        local function func(x, y)
            return x.index < y.index
        end

        table.sort(self.allItems, func)
    end

    local function reflushTemp(temp, index)
        if index <= 0 or index > number then
            return 
        end

        local parent = temp:getParent()
        if parent == nil then
            printWarn("temp not have parent")
            return 
        end

        local item = self:getItem(index - 1)
        if item == nil then
            printWarn("can not get item, item is nil")
            return 
        end
        
        temp:removeFromParent(false)
        item:addChild(temp)
        temp.index = index

        callback(temp, index)
    end

    local function initItem(item, index)
        local temp = grid:clone()
        temp:setVisible(true)
        temp:setPosition(cc.p(0, 0))
        temp:setAnchorPoint(cc.p(0, 0))
        temp.index = index
        temp:retain()
        item:addChild(temp)

        self.allItems[index] = temp
        callback(temp, index)
    end

    local function refreshItem(item, index) 
        local temp = self.allItems[index]
        temp.index = index
        local parent = temp:getParent()
        if parent then
            temp:removeFromParent()
        end
        item:addChild(temp)
        callback(temp, index)
    end

    local function checkAndRefreshItems()
        local percent = self:getPercent() / 100 --getPercent()c++里面重写的方法,取得当前当前位置与总距离的百分比
        if percent < 0 or percent > 100 then
            return 
        end

        innerSize = self:getInnerContainerSize()
        local index = 0
        if direction == cc.SCROLLVIEW_DIRECTION_HORIZONTAL then
            index = math.ceil((innerSize.width - size.width) * percent / offset)
        elseif direction == cc.SCROLLVIEW_DIRECTION_VERTICAL then
            index = math.ceil((innerSize.height - size.height) * percent / offset)
        end

        if index > 1 then
            index = index - 1
        end

        sortItems()
        local i = 0
        for _, v in pairs(self.allItems) do 
            if v.index < index then
                reflushTemp(v, index + showNum - 1 - i)
            elseif v.index > index + showNum - 1 then
                reflushTemp(v, index + showNum - (i + 1))
            end

            i = i + 1
        end
    end

    local function listViewCallBack(event)
        if event.name == "SCROLLING" then
            checkAndRefreshItems()
        end
    end  

    local default = ccui.Widget:create()
    default:setContentSize(gridSize)
    self:setItemModel(default)
    for i = 1, number do 
        if i <= showNum then
            local item = default:clone()
            if self.allItems[i] then
                refreshItem(item, i)
            else
                initItem(item, i)
            end

            self:pushBackCustomItem(item)
        else
            self:pushBackDefaultItem()
        end
    end

    for k, v in pairs(self.allItems) do 
        if k > number then
            v:release()
            self.allItems[k] = nil
        end
    end

    self:refreshView()
    self:onScroll(listViewCallBack)
    checkAndRefreshItems()
end

function ListView:clearUp()
    self.allItems = self.allItems or {}
    for k, v in pairs(self.allItems) do 
        v:release()
        self.allItems[k] = nil
    end
    self:removeAllItems()
end

function ListView:getShowItems()
    return self.allItems or {}
end

实际调用时

local all = {}
for i=1, 100 do 
    table.insert(all, i)
end

local function updateTemp(temp, index)
    local info = all [index]
    if info == nil then
      	return 
    end

    print("item "..info )
    --temp:getChildByName("num"):setString(info)
end

self.listView_1:tableShow(#all,  panel, updateTemp)

 

关注公众号【好便宜】( ID:haopianyi222 ),领红包啦~
阿里云,国内最大的云服务商,注册就送数千元优惠券:https://t.cn/AiQe5A0g
腾讯云,良心云,价格优惠: https://t.cn/AieHwwKl
搬瓦工,CN2 GIA 优质线路,搭梯子、海外建站推荐: https://t.cn/AieHwfX9
扫一扫关注公众号添加购物返利助手,领红包
Comments are closed.

推荐使用阿里云服务器

超多优惠券

服务器最低一折,一年不到100!

朕已阅去看看