cocos2d-lua 中使用控件 - TableView 实现不等高度时垂直浏览效果

各位安好,我在使用cocos2dx-v3.6版本中,使用tableview空间实现垂直的滑动效果。但是在lua-test中的实例代码实现的等宽距的滑动效果(@ExtensionTest.lua).鉴于源码中的注释很少的情况下,很多参数和作用只能通过不断尝试来理解作用。下面附上自己的实践代码,以便更好的说明问题:

-- HelloLayer 是一个cc.layer
function HelloLayer:initTableView()
    --[[
    @brief  滚动触发事件 scrollView滚动时,就调用该方法。任何offset值改变都调用该方法。即滚动过程中,调用多次 
    ]]
    local function scrollViewDidScroll(view)
        -- view 是当前tableview的实力,同下方的table
    end

    --[[
    @brief  // 当scrollView缩放时,调用该方法。在缩放过程中,回多次调用
    ]]
    local function scrollViewDidZoom(view)
    end

    --[[
    @brief  点击触碰事件
    ]]
    local function tableCellTouched(table,cell)
        print("cell touched at index: " .. cell:getIdx())
        -- cell:getIdx()来获取cell的index值
    end

    --[[
    @brief  两个cell之间宽高
    @return cell高度间隔,垂直滑动有效,
            cell宽度间隔,水平滑动有效。
    ]]
    local function cellSizeForTable(table,idx)
        return 100+10*idx, 0
        -- 依据index值来获取不等高的高度
    end

    --[[
    @brief  逐个创建cell
    ]]
    local function tableCellAtIndex(table, idx)
        local strValue = string.format("%d",idx)
        local cell = table:dequeueCell()
        local label = nil
        if nil == cell then
            cell = cc.TableViewCell:new()
            local sprite = display.newSprite("path to image")
            sprite:setAnchorPoint(cc.p(0,0))
            sprite:setPosition(cc.p(0, 0))
            local size = cc.size(963, 100+10*idx )  
            sprite:setContentSize(size)
            cell:addChild(sprite)
            label = cc.Label:createWithSystemFont(strValue, "Helvetica", 50)
            label:setColor( LBL_COLOR_BLACK )
            label:setPosition(cc.p(100,100))
            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

        return cell
    end


    --[[
    @brief  cell的数量设置
    ]]
    local function numberOfCellsInTableView(table)
       return 5
    end

    local tableView = cc.TableView:create( cc.size(963,561) )
    tableView:setDirection(cc.SCROLLVIEW_DIRECTION_VERTICAL)
    tableView:setPosition(cc.p(100,100)
    tableView:setDelegate()
    self:addChild(tableView)
    --registerScriptHandler functions must be before the reloadData funtion
    tableView:registerScriptHandler(numberOfCellsInTableView,cc.NUMBER_OF_CELLS_IN_TABLEVIEW)  
    tableView:registerScriptHandler(scrollViewDidScroll,cc.SCROLLVIEW_SCRIPT_SCROLL)
    tableView:registerScriptHandler(scrollViewDidZoom,cc.SCROLLVIEW_SCRIPT_ZOOM)
    tableView:registerScriptHandler(tableCellTouched,cc.TABLECELL_TOUCHED)
    tableView:registerScriptHandler(cellSizeForTable,cc.TABLECELL_SIZE_FOR_INDEX)
    tableView:registerScriptHandler(tableCellAtIndex,cc.TABLECELL_SIZE_AT_INDEX)
    tableView:reloadData()
end

在测试结果中会发现很难调控cell之间的间距,总会存在cell之间叠加的效果。
然后,我尝试把所有的cell的高度存在一个tabel中,如:local heightList = {100,150,200,250,300}
再次抱着希望尝试后,你会发现一个神奇的bug。随着不停的滑动,每次同一个id的cell高度会不断变化。我想这也证明了这里的idx和cell之间不是映射关系,不在可见范围内的cell会被清除,每次滑到可见区域中时重新创建的。

再次回到问题中心,我们需要怎么实现不等高的cell来实现tableview呢?独木难成林,希望能有好心热心的同道友人一起出谋划策,多谢 :)

阅读 10k
1 个回答

table:dequeueCell() 你都把它重用了还说会被清除?

文件的关键:
local size = cc.size(963, 100+10*idx )

        sprite:setContentSize(size) 

这种操作是有问题的

tableview实际上只创建了同屏能显示的数量+1个的cell
所以从+2开始都是在复用,这个时候复用的cell你并没有重新设置它的setContentSize

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
宣传栏