TableView制作聊天界面

模拟聊天

local names = {'Tom','Jack','Messi','Kaka','Beckham'}

local contents = {'An old gentleman whose eyesight was failing came to stay in a hotel room with a bottle of wine in each hand. On the wall there was a fly which he took for a nail. So the moment he hung them on, the bottles fell broken and the wine spilt all over the floor. When a waitress discovered what had happened, she showed deep sympathy for him and decided to do him a favour.',
    'So the next morning when he was out taking a walk in the roof garden, she hammered a nail exactly where the fly had stayed.',
    'Now the old man entered his room. The smell of the spilt wine reminded him of the accident. When he looked up at the wall, he found the fly was there again! He walked to it carefully adn slapped it with all his strength. On hearing a loud cry, the kind-hearted waitress rushed in. To her great surprise, the poor old man was there sitting on the floor, his teeth clenched and his right hand bleeding!',
    'A patron in Montreal cafe turned on a tap in the washroom and got scalded. "This is an outrage," he complained. "The faucet marked C gave me boiling water."',
    'Three competing store owners rented adjoining shops in a mall. Observers waited for mayhem to ensue.'}

local chatPool = {}
local size = 10
local id = 0

chatPool暂存聊天数据,size为pool的长度,id可以记录共有多少条聊天,也是聊天的编号。

function MainScene:pushBackChat()
    local i = math.random(1,5)
    id = id + 1
    local chat = {id=id,name=names[i],content=contents[i]}
    if #chatPool < size then
        table.insert(chatPool,chat)
    else
        table.remove(chatPool,1)
        table.insert(chatPool,chat)
    end
end

function MainScene:getLastChat()
    if #chatPool > 0 then
        return chatPool[#chatPool]
    else
        return {id=0,name='system',content='welcome'}
    end
end

function MainScene:beginListener()
    local function listener()
        local chat = self:getLastChat()
        local id = chat['id']
        if self.lastId ~= id then  -- 有新的聊天
            self.tv:reloadData() 
            if self.tv:cellAtIndex(0) then
                local cell = self.tv:cellAtIndex(0) 
                if cell:getPositionY() > 120 then
                    self.tv:setContentOffset(cc.p(0,0),false) 
                end
            end
            self.lastId = id
        end
    end
    local seq = cc.Sequence:create(cc.CallFunc:create(listener),cc.DelayTime:create(1.1))
    self:runAction(cc.RepeatForever:create(seq))
end

pushBackChat方法是往chatPool中压入一条数据,左上角放置一个按钮,点击之后会压入一条数据。getLastChat得到最后一条数据。beginListener方法中每隔1.1秒,检查有没有新的聊天。

以下是完整的代码:

local MainScene = class("MainScene", cc.load("mvc").ViewBase)

local names = {'Tom','Jack','Messi','Kaka','Beckham'}

local contents = {'An old gentleman whose eyesight was failing came to stay in a hotel room with a bottle of wine in each hand. On the wall there was a fly which he took for a nail. So the moment he hung them on, the bottles fell broken and the wine spilt all over the floor. When a waitress discovered what had happened, she showed deep sympathy for him and decided to do him a favour.',
    'So the next morning when he was out taking a walk in the roof garden, she hammered a nail exactly where the fly had stayed.',
    'Now the old man entered his room. The smell of the spilt wine reminded him of the accident. When he looked up at the wall, he found the fly was there again! He walked to it carefully adn slapped it with all his strength. On hearing a loud cry, the kind-hearted waitress rushed in. To her great surprise, the poor old man was there sitting on the floor, his teeth clenched and his right hand bleeding!',
    'A patron in Montreal cafe turned on a tap in the washroom and got scalded. "This is an outrage," he complained. "The faucet marked C gave me boiling water."',
    'Three competing store owners rented adjoining shops in a mall. Observers waited for mayhem to ensue.'}

local chatPool = {}
local size = 10
local id = 0

function MainScene:ctor()
    self:enableNodeEvents()
    self.lastId = 0
end

function MainScene:onEnter()
    self:createUI()
    self:beginListener()
end

function MainScene:pushBackChat()
    local i = math.random(1,5)
    id = id + 1
    local chat = {id=id,name=names[i],content=contents[i]}
    if #chatPool < size then
        table.insert(chatPool,chat)
    else
        table.remove(chatPool,1)
        table.insert(chatPool,chat)
    end
end

function MainScene:getLastChat()
    if #chatPool > 0 then
        return chatPool[#chatPool]
    else
        return {id=0,name='system',content='welcome'}
    end
end

function MainScene:createUI()
    self.tv = cc.TableView:create(cc.size(600,370))
    self:addChild(self.tv,1)
    self.tv:setPosition(150,140)
    self.tv:setVerticalFillOrder(cc.TABLEVIEW_FILL_TOPDOWN)
    self.tv:setDirection(cc.SCROLLVIEW_DIRECTION_VERTICAL)

    local function cellSizeForTable(table,idx) -- 第一个返回的是高度    第二个返回的是宽度
        local content = self.newTTFLabel({text = chatPool[idx+1]['content'],font = "fonts/DFYUANW7-GB2312.ttf",size = 23})
        content:setDimensions(500,0)
        return content:getContentSize().height+30,100
    end
    local function  tableCellAtIndex(table, idx)
        local cell = table:dequeueCell()

        local function initCell()
            local name = self.newTTFLabel({text = chatPool[idx+1]['id']..'.'..chatPool[idx+1]['name']..':',font = "fonts/DFYUANW7-GB2312.ttf",size = 23})
            name:setTextColor(cc.c3b(246,196,16))

            local content = self.newTTFLabel({text = chatPool[idx+1]['content'],font = "fonts/DFYUANW7-GB2312.ttf",size = 23})
            content:setDimensions(500,0)
            content:setTextColor(cc.c3b(104,229,255))
            content:setAnchorPoint(0,0)
            content:setPosition(25+name:getContentSize().width,2)
            content:setName('content')
            cell:addChild(content)

            name:setAnchorPoint(0,1)
            name:setPosition(20,content:getContentSize().height+2)
            name:setName('NAME')
            cell:addChild(name)
        end
        if not cell then
            cell = cc.TableViewCell:new()
            local content = self.newTTFLabel({text = chatPool[idx+1]['content'],font = "fonts/DFYUANW7-GB2312.ttf",size = 23})
            content:setDimensions(400,0)
            cell:setContentSize(100,content:getContentSize().height)
            cell:reset()
        else
            cell:removeAllChildren()
        end
        initCell()
        return cell
    end
    local function numberOfCellsInTableView(table)
        return #chatPool 
    end
    self.tv:registerScriptHandler(numberOfCellsInTableView,cc.NUMBER_OF_CELLS_IN_TABLEVIEW)  
    self.tv:registerScriptHandler(cellSizeForTable,cc.TABLECELL_SIZE_FOR_INDEX)
    self.tv:registerScriptHandler(tableCellAtIndex,cc.TABLECELL_SIZE_AT_INDEX)
    self.tv:reloadData()

    local btn = ccui.Button:create('res/DS07.png','res/DS08.png','res/DS09.png')
    btn:setPosition(100,550)
    self:addChild(btn)
    btn:addTouchEventListener(function(sender,_type)
        if _type == 2 then
            self:pushBackChat()
        end
    end)
end

function MainScene:beginListener()
    local function listener()
        local chat = self:getLastChat()
        local id = chat['id']
        if self.lastId ~= id then  -- 有新的聊天
            self.tv:reloadData() 
            if self.tv:cellAtIndex(0) then
                local cell = self.tv:cellAtIndex(0) 
                if cell:getPositionY() > 120 then
                    self.tv:setContentOffset(cc.p(0,0),false) 
                end
            end
            self.lastId = id
        end
    end
    local seq = cc.Sequence:create(cc.CallFunc:create(listener),cc.DelayTime:create(1.1))
    self:runAction(cc.RepeatForever:create(seq))
end

function MainScene.newTTFLabel(config)
    local myLabel= nil
    if config then
        if config.font then
            local mytext = ""
            local color = cc.c3b(255, 255, 255)
            local size = 22
            local align = cc.TEXT_ALIGNMENT_CENTER
            local vertical = cc.VERTICAL_TEXT_ALIGNMENT_CENTER
            if config.text then 
                mytext = config.text
            end
            if config.color then 
                color = config.color
            end
            if config.size then 
                size = config.size
            end
            if config.vertical then
                vertical = config.vertical
            end
            myLabel= cc.Label:createWithTTF(mytext,config.font,size)
        end
    end
    return myLabel
end

return MainScene

需要注意cellSizeForTable方法第一个返回的是高度,第二个返回的是宽度。
运行结果:
这里写图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值