【Cocos2d-x Lua】自定义TableView

本文介绍了一种自定义的TableLayer,它继承自CCLayer,允许设置表格的行数和列数,并能自动排列添加的CCNode对象。通过实现addCell方法和nextCell方法,可以创建一个可扩展且自动排序的表格。当TableLayer被添加到CCScrollView中时,可以实现可滑动的TableView效果。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


效果



    实现一个自定义的TableLayer,该Layer具有以下特性

   1. 该TableLayer可以在create的时候可以设置表格的行数和列数

   2. 该TableLayer具有一个addCell方法可以添加CCNode对象到表格

   3. 该TableLayer可以自动对表格中的CCNode对象进行排列


   假设行数为3,列数为3时,通过TableLayer的addCell方法添加12个宽和高相同的CCNode对象,它们的添加顺序和位置如下图所示:

   


    可以看出表格可以不断向右扩展,而且单元格自动排序,如果把该TableLayer添加到CCScrollView的container中,就可以实现一个可滑动的自定义TableView了。



实现思路


  1. TableLayer继承CCLayer

  2. TableLayer通过构造函数传入表格列数、行数、单元格宽、高

  3. TableLayer提供了一个addCell方法添加单元格(CCNode对象)

  4. addCell方法先调用nextCell方法获取单元格的坐标(由单元格的列数和行数组成),然后调用positionByColumnAndRow方法根据单元格坐标获取该单元格的位置,最后      调用CCNode的setPosition方法设置位置并添加到TableLayer中。


   如何知道单元格的位置?

   1.首先需要知道单元格的所在的列和行,通过nextCell方法获取,具体逻辑下面的代码有说明。 

    2.然后根据单元格的宽、高,表格的高度计算单元格的的x,y坐标。

    第一列为1,第一行为1

    x = 单元格宽度 * (单元格所在列 - 1)+ 单元格宽度 / 2

    y = 表格高度 - (单元格高度 * (单元格所在行 - 1)+  单元格高度 / 2)(注意:cocos2d-x坐标是以左下角为原点,而这里单元格坐标是以左上角为原点)


实现代码


Lua代码:

-- 表格控件
TableLayer = class("TableLayer",function ()
    return CCLayer:create()
end)

-- 创建一个TableLayer
--kCCScrollViewDirectionHorizontal    -- 水平滚动
--kCCScrollViewDirectionVertical        -- 竖直滚动
-- direction    方向
-- column      可视区域的列数
-- row            可视区域的行数
-- cellWidth    单元格宽度
-- cellHeight   单元格高度
function TableLayer:create(direction, column, row, cellWidth, cellHeight)
    local layer = TableLayer.new()
    layer:init(direction, column, row, cellWidth, cellHeight)
    return layer
end


-- 根据单元格坐标计算出单元格的位置
local function positionByColumnAndRow_H(self, column, row)
    local x = self.cellWidth*(column-1) + self.cellWidth/2
    local y = self.height - self.cellHeight*(row-1) - self.cellHeight/2 -- 需要转换为UI坐标
    --    cclog("positionByColumnAndRow column=%d row=%d x=%f y=%f", column, row, x, y)
    return x,y
end
-- 单元格坐标计算逻辑
local function nextCell_H(self)
    local column = self.nextColumn
    local row = self.nextRow

    -- 计算下一个单元格的坐标
    if column < self.column then    -- 在指定列内
        self.nextColumn = self.nextColumn + 1
    elseif column == self.column then   -- 达到指定列
        -- 到达指定行,换列
        if row == self.row then
            self.nextColumn = column + 1
            self.nextRow = 1
    else
        -- 未到达指定行,换行
        self.nextColumn = 1
        self.nextRow = row + 1
    end
    else
        -- 到达指定行,+列
        if row == self.row then
            self.nextColumn = column + 1
            self.nextRow = 1
        else
            self.nextRow = row + 1
        end
    end
    cclog("nextCell column=%d row=%d",column,row)
    self.curColumn = column
    return column,row
end
-- 获取下一个单元格位置
local function nextPosition_H(self)
    return positionByColumnAndRow_H(self,nextCell_H(self))
end
-- 添加表格
local function addCell_H(self, cell)
    cell:setAnchorPoint(ccp(0.5,0.5))
    cell:setPosition(nextPosition_H(self))
    self:addChild(cell)
    self:setContentSize(CCSize(self.curColumn * self.cellWidth, self.height))
end

-- 根据表格坐标获取位置
local function getPosByCellCoord(self, column, row)
    local x = self.cellWidth/2 + (column-1)*self.cellWidth   
    local y = self.cellHeight/2 + (self.curRow - row)*self.cellHeight
    return x,y
end
local function addCell_V(self, cell)
    cell:setAnchorPoint(ccp(0.5,0.5))
    table.insert(self.cells,cell)
    self.curRow = math.ceil(#self.cells/self.column)

    --    更新所有单元格位置
    local column = nil
    local row = nil
    for i=1, #self.cells do
        local temp = self.cells[i]
        -- 计算单元格所在列        
        column = i%self.column
        column = if_else(column==0,self.column,column) -- 边界判断
        -- 计算单元格所在行(从最高往下)        
        row = math.ceil(i/self.column)
        -- 更新位置        
        temp:setPosition(ccp(getPosByCellCoord(self, column,row)))
    end
    
    self:addChild(cell)
    -- 更新大小
    self:setContentSize(CCSize(self.width, self.curRow * self.cellHeight))
end

-- 初始化
function TableLayer:init(direction, column, row, cellWidth, cellHeight)
    self.direction = direction
    -- 列
    self.column = column
    -- 行
    self.row = row
    -- 列宽
    self.cellWidth = cellWidth
    -- 列高
    self.cellHeight = cellHeight
    -- 下一行
    self.nextColumn = 1
    self.curColumn = 1
    -- 下一列
    self.nextRow = 1
    -- 表格宽高
    self.width = column * cellWidth
    self.height = row * cellHeight
    -- 方向判断
    if self.direction == kCCScrollViewDirectionHorizontal then
        self.addCellFuc = addCell_H
    else
        self.cells = {}
        self.addCellFuc = addCell_V
    end
end

-- 添加单元格
function TableLayer:addCell(cell)
    return self.addCellFuc(self,cell)
end

function TableLayer:getTableView()
    if self.scrollView == nil then
        self.scrollView = CCScrollView:create(CCSizeMake(self.column * self.cellWidth, self.row * self.cellHeight), self)
        --        cclog("ViewSize width=%s height=%s,ContainerSize width=%s height=%s",self.column * self.cellWidth, self.row * self.cellHeight,self:getContentSize().width,self:getContentSize().height)
        -- 设置滚动方向
        self.scrollView:setDirection(self.direction)
    end
    return self.scrollView
end

调用示例:

        local tabLayer = TableLayer:create(kCCScrollViewDirectionVertical,1,4,565,70)
        tabLayer:addCell(CCSprite:create("res/ui/shop/item1.png"))        
        tabLayer:addCell(CCSprite:create("res/ui/shop/item2.png"))        
        tabLayer:addCell(CCSprite:create("res/ui/shop/item3.png"))        
        tabLayer:addCell(CCSprite:create("res/ui/shop/item4.png"))        
        tabLayer:addCell(CCSprite:create("res/ui/shop/item5.png"))        
        local tabView = tabLayer:getTableView()
        tabView:setPosition(285,115)
        layer:addChild(tabView)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值