cocos2d-lua 3.4版本的富文本[转载的]
-- Author: zlf -- Date: 2016年5月9日17:05:37 -- 简易富文本 RichText = class("RichText", function() return ccui.Layout:create() end) --自适应最大宽度,自动换行 RichText.auto = 1 --系统公告,无限宽 RichText.gmnotice = 2 local cache = cc.SpriteFrameCache:getInstance() --[[ @param data 富文本参数(table) data示例:{{txt="12呵呵asdasad###3", color="#FF9966", isUnLine = 1, data = "函数回调参数"}, {img = "Star.png", data = "函数回调参数"}} 使用方式: local richLabel = RichText:create() setDrawType可用可不用,但是create之后一定要手动调用init函数 richLabel:setDrawType(1) richLabel:init(param, 300) richLabel:setPosition(300, 320) self:addChild(richLabel) data里面元素作用详解: txt代表要创建的控件是ccui.Text,img则代表ccui.ImageView, color设置ccui.Text的字体颜色 isUnLine用来表示ccui.Text是否需要下划线,nil或者false代表不画, data作为控件回调函数的参数 fontSize用来设置ccui.Text的字体大小 @param maxWidth 富文本的最大宽度,设置了最大宽度,可以自动换行 @param globalCallBack 全局回调函数,当这个参数存在时,所有的控件回调都调用这个函数 @param globalFontSize 全局字体大小,当这个参数存在时,所有的ccui.Text的字体大小都设置为这个参数 @param this 类指针,callback(this, callParam)这个作用,语法糖 ]] function RichText:create() local ret = RichText.new() return ret end --2016年6月12日19:53:03 去掉了几个全局参数 callback字段也不用了 -- function RichText:init(param, maxWidth, globalCallBack, globalColor, globalFontSize, this) function RichText:init(param, maxWidth, globalCallBack, this) if type(param) ~= "table" then return end self:removeAllChildren() self.globalCallBack = globalCallBack self.globalFontSize = globalFontSize self.renderWidth = 0 self.renderLine = 0 maxWidth = maxWidth or 400 local curWidth = 0 local row = 0 local curIndex = 1 local allWidget = {} for i=1,#param do local x, y = 0 if param[i].txt and param[i].txt ~= "" then local textTb = Utils.separate(param[i].txt) for j=1,#textTb do local color = self:getNeedColor(globalColor, param[i].color) local widget = self:getLabel(textTb[j], color, globalCallBack, param[i].data, globalFontSize or param[i].fontSize, this) widget.isUnLine = param[i].isUnLine local size = widget:getContentSize() x, y = curWidth, size.height * row local width = size.width if curWidth + width > maxWidth then curWidth = width row = row - 1 curIndex = curIndex + 1 x, y = 0, size.height * row else curWidth = curWidth + width end if not allWidget[curIndex] then allWidget[curIndex] = {} end table.insert(allWidget[curIndex], widget) widget:setPosition(x, y) widget:setAnchorPoint(cc.p(0, 0.5)) widget.trueRow = curIndex self:addChild(widget) end elseif param[i].img then local widget = self:getImage(param[i].img, globalCallBack, globalParam or param[i].data, this) local size = widget:getContentSize() x, y = curWidth, size.height * row if curWidth + size.width > maxWidth then curWidth = size.width row = row - 1 curIndex = curIndex + 1 x, y = 0, size.height * row else curWidth = curWidth + size.width end if not allWidget[curIndex] then allWidget[curIndex] = {} end table.insert(allWidget[curIndex], widget) widget:setAnchorPoint(cc.p(0, 0.5)) widget:setPosition(x, y) self:addChild(widget) elseif param[i].anim then end end self.renderWidth = curIndex > 1 and maxWidth or curWidth self.renderLine = curIndex self:adjust(allWidget) end function RichText:setDrawType(type) self.DrawType = type end function RichText:setRowSpace(space) self.rowSpace = space end function RichText:adjust(allWidget) self.DrawType = self.DrawType or self.auto self.renderHeight = 0 if self.DrawType == self.auto then self.rowSpace = self.rowSpace or 0 local _max = {} for i=1,#allWidget do local maxHeight = 0 for k,v in pairs(allWidget[i]) do local size if v.isAnim then size = v.size else size = v:getContentSize() end if size.height * 0.5 > maxHeight then maxHeight = size.height * 0.5 + self.rowSpace end end self.renderHeight = self.renderHeight + maxHeight if i == 1 then self.posX = maxHeight - self.rowSpace end if maxHeight > 0 then if _max[i-1] then _max[i] = maxHeight*2 + _max[i-1] else _max[i] = maxHeight end for k,v in pairs(allWidget[i]) do local height = 0 if _max[i-1] then height = -maxHeight - _max[i-1] else height = 0 end v:setPositionY(height) if v.isUnLine then self:drawUnLine(self, v) end end end end self:setContentSize(cc.size(self.renderWidth, self.renderHeight)) else local all = {} local allWidth = {} local maxHeight = -100 for k,v in pairs(allWidget) do for key,value in pairs(v) do local size if value.isAnim then size = value.size else size = value:getContentSize() end if size.height * 0.5 > maxHeight then maxHeight = size.height * 0.5 end table.insert(all, value) table.insert(allWidth, value:getContentSize().width) end if k == 1 then self.posX = maxHeight end end self.renderHeight = maxHeight local curWidth = 0 for i=1,#all do all[i]:setPosition(curWidth, 0) curWidth = curWidth + allWidth[i] self.renderWidth = curWidth if all[i].isUnLine then self:drawUnLine(self, all[i]) end end self.renderLine = 1 end self:setContentSize(cc.size(self.renderWidth, 0)) end function RichText:getRenderWidth() return self.renderWidth end function RichText:getRenderLine() return self.renderLine end function RichText:getRenderHeight() return self.renderHeight end function RichText:drawUnLine(parent, widget) local color4F = cc.convertColor(widget:getColor(), "4f") color4F.a = 1 local pos = cc.p(widget:getPosition()) self:getDrawNode(parent):drawLine(cc.p(pos.x, pos.y - widget:getContentSize().height/2), cc.p(pos.x + widget:getContentSize().width, pos.y - widget:getContentSize().height/2), color4F) end function RichText:getDrawNode(parent) if not self.drawNode then self.drawNode = cc.DrawNode:create() parent:addChild(self.drawNode) end return self.drawNode end function RichText:getLabel(param, color, callback, funcParam, fontSize, this) local text = ccui.Text:create() text:setFontName("Arial") text:setFontSize(fontSize or 22) text:setString(param) if color then text:setColor(color) end if funcParam then text:setTouchEnabled(true) if type(callback) == "function" then text:addTouchEventListener(function(sender, event) if event == ccui.TouchEventType.ended then if this then callback(this, funcParam) else callback(funcParam) end end end) end end text:enableShadow(cc.c4b(0,0,0,255), cc.size(1,-1)) return text end function RichText:getImage(param, callback, callParam, this) local img = ccui.ImageView:create() if not cache:getSpriteFrame(param) then img:loadTexture(param) else img:loadTexture(param, ccui.TextureResType.plistType) end if callParam then img:setTouchEnabled(true) if type(callback) == "function" then img:addTouchEventListener(function(sender, event) if event == ccui.TouchEventType.ended then if this then callback(this, callParam) else callback(callParam) end end end) end end return img end function RichText:getNeedColor(p1, p2) local result if p1 then result = p1 elseif p2 then result = p2 else result = cc.c3b(255,255,255) end if type(result) == "string" then result = Utils.str2Color(result) end return result end function RichText:setPos(x, y) self.posX = self.posX or 0 if type(x) == "table" then x.y = x.y - self.posX self:setPosition(x) else y = y - self.posX self:setPosition(x, y) end end