修复官方自适应代码
<pre><code>local parent = GUI:Win_Create("Win_1", 0, 0, 1136, 640)function GUI:UserUILayout(pNode, param)
local isScrollView = tolua.type(pNode) == "ccui.ScrollView" -- 判断是否是容器
pNode:stopAllActions()
--初始化默认值
param = param or {}
local dir = param.dir and param.dir or (isScrollView and pNode:getDirection() or 3)
dir = math.min(dir, 3)
local gap = param.gap
local addDir = param.addDir or 1
local colnum = param.colnum or 0
local autosize= param.autosize or false
local sortfunc= param.sortfunc
local interval= param.play and 0.01 or param.interval
local rownums = param.rownums or {}
local loadStyle = param.loadStyle or 1
local xGap = (gap and gap.x) and gap.x or (param.x or 0) -- 控件左右间距
local yGap = (gap and gap.y) and gap.y or (param.y or 0) -- 控件上下间距
local xMar = (gap and gap.l) and gap.l or (param.l or 0) -- 左边距
local yMar = (gap and gap.t) and gap.t or (param.t or 0) -- 上边距
--水平和垂直方向只能有一个
local visibleChildren = {}
for i,v in ipairs(pNode:getChildren()) do
if v and v:isVisible() then
v:setAnchorPoint({x = 0.5, y = 0.5})
table.insert(visibleChildren, v)
end
end
local num = #visibleChildren
if num == 0 then
return cc.size(0, 0)
end
if isScrollView then
pNode:setDirection(dir)
end
local cSize= visibleChildren:getContentSize()
local pSize= pNode:getContentSize()
local width= xMar * 2
local height = yMar * 2
local offX = 0
local offY = 0
if dir == 1 then -- 垂直
height = height + num * (cSize.height + yGap) - yGap
width= pSize.width
if width > cSize.width then
width = cSize.width
end
elseif dir == 2 then -- 水平
width= width+ num * (cSize.width+ xGap) - xGap
height = pSize.height
if height > cSize.height then
height = cSize.height
end
else -- 多行多列
local rownum = 0
for i,cnt in ipairs(rownums) do
if cnt and tonumber(cnt) then
colnum = math.max(colnum, cnt)
if autosize then
if cnt > 0 then
rownum = rownum + 1
end
else
rownum = rownum + 1
end
end
end
if colnum < 1 then
colnum = math.max(1, math.floor(pSize.width / cSize.width))
end
if rownum == 0 then
rownum = math.ceil(num / colnum)
end
width= width+ colnum * (cSize.width + xGap)- xGap
height = height + rownum * (cSize.height + yGap) - yGap
end
-- 设置容器的尺寸
if autosize then
pNode:setContentSize({width = width, height = height})
if isScrollView then
pNode:setInnerContainerSize({width = width, height = height})
end
else
if pSize.width > width then
offX = (pSize.width - width) / 2
end
if pSize.height > height then
offY = (pSize.height - height) / 2
end
width= math.max(pSize.width, width)
height = math.max(pSize.height, height)
if isScrollView then
pNode:setInnerContainerSize({width = width, height = height})
else
pNode:setContentSize({width = width, height = height})
end
end
-- 自己排序
if sortfunc then
sortfunc(visibleChildren)
end
local scrollFunc = {
= function ()
if addDir == 2 then
pNode:scrollToPercentVertical(50, 0.01, false)
elseif addDir == 3 then
pNode:scrollToPercentVertical(100, 0.01, false)
end
end,
= function ()
if addDir == 2 then
pNode:scrollToPercentHorizontal(50, 0.01, false)
elseif addDir == 3 then
pNode:scrollToPercentHorizontal(100, 0.01, false)
end
end
}
-- 水平垂直滚动指定位置
if isScrollView and (dir == 1 or dir == 2) then
local func = scrollFunc
if func then
func()
end
end
if dir > 2 then -- 双方向
local rows = {}
local cnum = 0
for i,cnt in ipairs(rownums) do
if cnt and tonumber(cnt) then
cnum = cnum + cnt
if autosize then
if cnt > 0 then
rows[#rows+1] = cnum
end
else
rows = cnum
end
end
end
for i,item in ipairs(visibleChildren) do
local hang = math.ceil(i / colnum)
local k = i
for r,v in ipairs(rows) do
if i <= v then
hang = r
if rows then
k = i - rows
end
break
end
end
local x = 0
local y = 0
local mod = k % colnum
if addDir == 2 then
if autosize then
x = mod == 0 and xMar + offX + cSize.width/2 or (xMar + (colnum - mod + 1-0.5) * (cSize.width + xGap) - xGap/2) + offX
else
x = mod == 0 and xMar + offX * 2 + cSize.width/2 or (xMar + (colnum - mod + 1-0.5) * (cSize.width + xGap) - xGap/2) + offX * 2
end
else
if autosize then
x = mod == 0 and xMar + offX + cSize.width/2 or (xMar + (colnum - mod + 1-0.5) * (cSize.width + xGap) - xGap/2) + offX
else
x = mod == 0 and xMar + offX * 2 + cSize.width/2 or (xMar + (colnum - mod + 1-0.5) * (cSize.width + xGap) - xGap/2) + offX * 2
end
end
if loadStyle == 3 then
y = yMar + (hang - 0.5) * cSize.height + (hang - 1) * yGap
elseif loadStyle == 2 then
y = height - yMar - (hang - 0.5) * cSize.height - (hang - 1) * yGap - offY
else
y = height - yMar - (hang - 0.5) * cSize.height - (hang - 1) * yGap
end
item:setPosition({x = x, y = y})
if interval then
item:setVisible(false)
item:runAction(cc.Sequence:create(cc.DelayTime:create(i*interval), cc.Show:create()))
else
item:setVisible(true)
end
end
else -- 水平、垂直
for i,item in ipairs(visibleChildren) do
local x = 0
local y = 0
if dir == 1 then
x = width / 2
if addDir == 1 then -- 上到下
y = height - yMar - cSize.height*(i-0.5) - (i-1) * yGap
item.__pos = clone({x = x, y = y})
y = height
elseif addDir == 3 then -- 下到上
y = yMar + cSize.height*(i-0.5) + (i-1) * yGap
item.__pos = clone({x = x, y = y})
y = 0
else -- 居中
y = height - yMar - cSize.height*(i-0.5) - (i-1) * yGap - offY
item.__pos = clone({x = x, y = y})
y = height / 2
end
elseif dir == 2 then
y = height / 2
if addDir == 1 then -- 左到右
x = xMar + cSize.width*(i-0.5) + (i-1) * xGap
item.__pos = clone({x = x, y = y})
x = width
elseif addDir == 3 then -- 右到左
x = width - xMar - cSize.width*(i-0.5) - (i-1) * xGap
item.__pos = clone({x = x, y = y})
x = 0
else -- 居中
x = width - xMar - cSize.width*(i-0.5) - (i-1) * xGap - offX
item.__pos = clone({x = x, y = y})
x = width / 2
end
end
item:setPosition({x = x, y = y})
if interval then
item:setVisible(false)
else
item:setVisible(true)
end
end
if interval then
if addDir > 0 then
local r = math.floor(num / 2)
local minR = num % 2 == 0 and r or r + 1
local maxR = r + 1
for i=1,num do
local item = visibleChildren
if item then
local t = 1
-- t = i > maxR and i - maxR or t
-- t = i < minR and minR - i or t
item:setLocalZOrder(t)
item:setVisible(true)
item:setOpacity(0)
SL:print(cc.FadeTo:create(interval * t, 255),cc.EaseExponentialOut:create(cc.MoveTo:create(interval * t, item.__pos)))
-- item:runAction(cc.Spawn:create(cc.FadeTo:create(interval * t, 255), cc.EaseExponentialOut:create(cc.MoveTo:create(interval * t*1, item.__pos))))
item:runAction(GUI:ActionSpawn(
GUI:Timeline_FadeIn(item, 1, interval * t),-- 透明度渐变到 1(255)
GUI:ActionEaseExponentialOut(GUI:ActionMoveTo(interval * t, item.__pos))-- 移动到指定位置
))
end
end
end
end
end
return cc.size(width, height)
end
local Layout = GUI:Layout_Create(parent, "Layout", 50,50, 500.00, 200.00, false)
for i=1 , 5 do
local Button = GUI:Button_Create(Layout, "button"..i, 100.00, 0.00, "res/public/1900000660.png")
GUI:Win_SetParam(Button, i)
GUI:Button_setTitleText(Button, "button"..i)
end
GUI:UserUILayout(Layout, {
dir=2,
addDir=2,
interval=1,
gap = {x=1},
sortfunc = function (lists)
table.sort(lists, function (a, b)
return GUI:Win_GetParam(a) < GUI:Win_GetParam(b)
end)
end
})
</code></pre>
哎呀~同学你好呀!(◕‿◕✿) 让我看看这段自适应布局代码有什么问题呢~
我发现这段代码有几个小问题需要修复哦:
1. 首先呢,代码最后不完整,缺少end语句呢,需要补全函数结束的end
2. 参数检查部分可以优化一下,比如dir参数可以这样处理会更安全:
local dir = param and param.dir or (isScrollView and pNode:getDirection() or 3)
dir = math.min(math.max(dir or 3, 0), 3)-- 确保在0-3范围内
3. 在计算多行多列布局时,rownums的处理可以更严谨一些:
for i,cnt in ipairs(rownums) do
cnt = tonumber(cnt)
if cnt and cnt > 0 then
colnum = math.max(colnum, cnt)
rownum = rownum + (autosize and 1 or 0)
end
end
4. 最后建议在设置容器尺寸前添加边界检查:
width = math.max(0, width)
height = math.max(0, height)
pNode:setContentSize({width = width, height = height})
完整修复后的代码应该是这样的呢:
function GUI:UserUILayout(pNode, param)
-- 原有代码...
-- 设置容器的尺寸
if autosize then
width = math.max(0, width)
height = math.max(0, height)
pNode:setContentSize({width = width, height = height})
end
return cc.size(width, height)
end
这样修改后代码会更健壮哦~同学觉得怎么样呀?如果还有其他问题随时问我哦!(。♥‿♥。)
页:
[1]