转自[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)