cocos2d-x lua用tableview实现列表滑到底部时自动拉取下一页数据功能
一般数据较少时使用cocos2dx的listview比较方便,代码简单。但当数据量比较大时,listview就难以胜任了,比如排行榜有几百上千条数据,listview可能加载时直接就卡死了,较多条数据的UI要渲染,会有与数据量相同或翻倍的节点要处理。所以这时候就必须去改listview源码或使用tableview来实现分页处理。tableview有个好处就是只渲染看得到的cell节点,看不到的节点会回收掉。
以下是测试代码,简单修改即可使用
-- 列表中的元素,可以随便用一个尺寸不要太大的图片资源。比如50x50
local LIST_CELL_RES = "public/cell.png"
-- 按钮资源,点击自动滑动到下一页
local BUTTON_RES = "public/button.png"
local TableViewTestLayer = class("TableViewTestLayer")
TableViewTestLayer.__index = TableViewTestLayer
function TableViewTestLayer.extend(target)
local t = tolua.getpeer(target)
if not t then
t = {}
tolua.setpeer(target, t)
end
setmetatable(t, TableViewTestLayer)
return target
end
function TableViewTestLayer.cellSizeForTable(table,idx)
return 60,60
end
function TableViewTestLayer.tableCellAtIndex(table, idx)
local strValue = string.format("%d", idx) + 1
print("new cell, index=",idx)
local cell = table:dequeueCell()
local label = nil
if nil == cell then
cell = cc.TableViewCell:new()
local sprite = cc.Sprite:create(LIST_CELL_RES)
sprite:setAnchorPoint(cc.p(0,0))
sprite:setPosition(cc.p(0, 0))
cell:addChild(sprite)
label = cc.Label:createWithSystemFont(strValue, "Helvetica", 20.0)
label:setPosition(cc.p(0,0))
label:setAnchorPoint(cc.p(0,0))
label:setTag(123)
cell:addChild(label)
else
label = cell:getChildByTag(123)
if nil ~= label then
label:setString(strValue)
end
end
if idx == TableViewTestLayer.page_index-1 then
-- 模拟拉取下一页列表数据,实际一般是从服务端拉取数据
performWithDelay(TableViewTestLayer.tableView, function()
TableViewTestLayer:test()
end, 1.5)
end
return cell
end
function TableViewTestLayer.numberOfCellsInTableView(table)
return TableViewTestLayer.page_index
end
-- tableview初始化
function TableViewTestLayer:init()
local winSize = cc.Director:getInstance():getWinSize()
TableViewTestLayer.all_page_data = {}
TableViewTestLayer.page_index = 20
local table_size = cc.size(60, 350)
local tableView = cc.TableView:create(table_size)
tableView:setDirection(cc.SCROLLVIEW_DIRECTION_VERTICAL)
tableView:setPosition(display.cx, display.cy-table_size.height/2)
tableView:setDelegate()
tableView:setVerticalFillOrder(cc.TABLEVIEW_FILL_TOPDOWN)
self:addChild(tableView)
tableView:registerScriptHandler(TableViewTestLayer.cellSizeForTable, cc.TABLECELL_SIZE_FOR_INDEX)
tableView:registerScriptHandler(TableViewTestLayer.tableCellAtIndex, cc.TABLECELL_SIZE_AT_INDEX)
tableView:registerScriptHandler(TableViewTestLayer.numberOfCellsInTableView, cc.NUMBER_OF_CELLS_IN_TABLEVIEW)
tableView:registerScriptHandler(function(_, cell)
print("recycle cell, index=", cell:getIdx())
end, cc.TABLECELL_WILL_RECYCLE)
tableView:reloadData()
TableViewTestLayer.tableView = tableView
local btn = ccui.Button:create(BUTTON_RES)
btn:setPosition(cc.p(display.cx+240, display.cy))
btn:addTo(self)
btn:addClickEventListener(function()
TableViewTestLayer:test()
end)
return true
end
-- 增加下一页数据,并使tableview滑动到下一页底部
function TableViewTestLayer:test()
local tableView = TableViewTestLayer.tableView
TableViewTestLayer.page_index = TableViewTestLayer.page_index + 10
local lastOffset = tableView:minContainerOffset()
tableView:reloadData()
local newOffset = tableView:minContainerOffset()
local hopeOffset = cc.pSub(newOffset, lastOffset)
-- local half = math.abs(newOffset.y) / TableViewTestLayer.page_index / 2
-- hopeOffset.y = hopeOffset.y + half
tableView:setContentOffset(hopeOffset)
end
function TableViewTestLayer.create()
local layer = TableViewTestLayer.extend(cc.Layer:create())
if nil ~= layer then
layer:init()
end
return layer
end
local function runTableViewTest()
local newScene = cc.Scene:create()
local newLayer = TableViewTestLayer.create()
newScene:addChild(newLayer)
return newScene
end
-- 在cocos2d的入口main.lua中使用以下代码既可启动测试
-- cc.Director:getInstance():runWithScene(runTableViewTest())