CocosCreator踩坑记录:Layout组件使用Grid布局后自适应高度不正常

Layout组件使用以下配置:


CocosCreator踩坑记录:Layout组件使用Grid布局后自适应高度不正常_第1张图片
1.png

效果如下图所示


CocosCreator踩坑记录:Layout组件使用Grid布局后自适应高度不正常_第2张图片
2.png

cocosCreator版本:1.9.2

这个效果明显不是我想要的,我想要的效果是卡牌不论有多少张,它们在垂直方向都能居中,而在实际效果图中我们看到明显是往上偏移了。
此时,观察到我们的这个Layout组件的高度值仅有一个卡牌高度的量(如一张卡牌高度是100,那么两张卡牌高度本应该是200,而我们这个Layout的实际高度仅有100),所以可以得到一个结论:问题出在Layout的高度计算代码有误。

解决方案
新建一个JavaScript文件,然后使其继承自cc.Layout,然后重写它在GRID这种Type情况下的垂直方向布局方法。


cc.Class({
    extends: cc.Layout,

    properties: {

    },

    //覆盖父类同名方法,代码取自父类方法,仅修改几个小细节
    _doLayoutGridAxisHorizontal(layoutAnchor, layoutSize){
        var baseWidth = layoutSize.width;

        var sign = 1;
        var bottomBoundaryOfLayout = -layoutAnchor.y * layoutSize.height;
        var paddingY = this.paddingBottom;
        if (this.verticalDirection === cc.Layout.VerticalDirection.TOP_TO_BOTTOM) {
            sign = -1;
            bottomBoundaryOfLayout = (1 - layoutAnchor.y) * layoutSize.height;
            paddingY = this.paddingTop;
        }

        //修改处1:此处根据sign的不同使用不同计算方式
        var fnPositionY = function(child, topOffset, row) {
            return sign === 1 ? (bottomBoundaryOfLayout + topOffset + child.anchorY * child.height + paddingY + row * this.spacingY) : 
            (bottomBoundaryOfLayout - topOffset - (1 - child.anchorY) * child.height - paddingY - row * this.spacingY);
        }.bind(this);

        //修改处2:resizeMode === CONTAINER时的高度计算方式修改
        this._doLayoutHorizontally(baseWidth, true, fnPositionY, true);

        if (this.resizeMode === cc.Layout.ResizeMode.CONTAINER) {
            var minY = Number.MAX_VALUE, maxY = Number.MIN_VALUE;
            for(var c of this.node.children)
            {
                if (c.activeInHierarchy) {
                    var b = c.getBoundingBox();
                    if(b.yMin < minY)minY = b.yMin;
                    if(b.yMax > maxY)maxY = b.yMax;
                }
            }

            var newHeight = maxY - minY;
            this.node.setContentSize(baseWidth, newHeight);

            bottomBoundaryOfLayout = sign === 1 ? (-layoutAnchor.y * newHeight) : ((1 - layoutAnchor.y) * newHeight);
            this._doLayoutHorizontally(baseWidth, true, fnPositionY, true);
        }
    }
});

使用此Javascript文件替代Layout作为布局组件即可解决问题,当然,要是你想修改官方cc.Layout的源码也行,就是步骤多一点,而且升级ccc之后还得重新写一遍。希望官方人员看到此贴后可以及时修改Layout中相关高度计算的源码。不过我这个只给出了自适应高度的计算代码,全当抛砖引玉了,自适应宽度的计算代码在此就不写了

你可能感兴趣的:(CocosCreator踩坑记录:Layout组件使用Grid布局后自适应高度不正常)