如何让自定义的统一LayoutGroup扩大以适应内容

问题描述 投票:0回答:1

我试图在this question的答案(上GitHub也高达)在需要它垂直调整,以遏制它的孩子的情况描述为使用自定义FlowLayoutGroup。

我的设置是这样的:

  • ScrollableRect 面板与VerticalLayoutGroup补偿(父scrollRect的内容)应该垂直调整,以适应儿童: 与FlowLayoutGroup小组应该垂直调整,以适应儿童 面板FlowLayoutGroup(2)也必须调整... 等等...

我添加了一个内容大小钳工到FlowLayoutGroup,调整了垂直组的布局儿童尺寸控制,但没有成功。

用户可以添加和删除组的儿童应用程序运行时,我想的UI响应,因此无法设置一切的高度提前。

我也期待在统一的源代码,试图找出如何写到组件这一点我自己。这看起来是最好的选择,但带我,因为我是新来的团结和C#相当长的时间。希望有人已经解决了类似的问题。

期望/预期除了LayoutGroups调整以垂直方向完全子女的缺失行为的一切功能。

我怎样才能做到这一点?

c# unity3d unity3d-2dtools unity3d-ui
1个回答
0
投票

过了一段时间,一个风滚草徽章我决定在把时间做一个解决方案,希望别人好处。

再次,这是the work done here的修改版本。感谢那。该组件现在计算它自己的首选大小。

主要变化:

  1. 我剥回相当严重: 所有水平覆盖被清空,我只需要水平包装行为 移除了网格布局类的一些明显的解酒变量
  2. 逻辑来计算孩子的位置和行的圈数,最佳高度是在它自己的方法。
  3. 子位置被存储在一个Vector2阵列以单独计算从子设置。

这修正了整个组件不能调整高度的问题,它也立即响应,与因为儿童rectTransforms设定那么把原来的脚本访问脚本花了两个“周期”来识别孩子的尺寸。

这适合我所有的需求,我想它可以很容易修改,以处理立式包装太...

using UnityEngine;
using UnityEngine.UI;

[AddComponentMenu("Layout/Wrap Layout Group", 153)]
public class WrapLayoutGroup : LayoutGroup
{
    [SerializeField] protected Vector2 m_Spacing = Vector2.zero;
    public Vector2 spacing { get { return m_Spacing; } set { SetProperty(ref m_Spacing, value); } }

    [SerializeField] protected bool m_Horizontal = true;
    public bool horizontal { get { return m_Horizontal; } set { SetProperty(ref m_Horizontal, value); } }

    private float availableWidth { get { return rectTransform.rect.width - padding.horizontal + spacing.x; } }

    private const float MIN_HEIGHT = 80;

    private int preferredRows = 1;
    private float calculatedHeight = MIN_HEIGHT;

    private Vector2[] childPositions = new Vector2[0];

    protected WrapLayoutGroup()
    { }

#if UNITY_EDITOR
    protected override void OnValidate()
    {
        base.OnValidate();
    }

#endif

    public override void CalculateLayoutInputVertical()
    {
        calculatePositionsAndRequiredSize();
        SetLayoutInputForAxis(calculatedHeight, calculatedHeight, -1, 1);
    }

    public override void SetLayoutHorizontal() { }

    public override void SetLayoutVertical()
    {
        SetChildren();
    }

    private void SetChildren()
    {
        for (int i = 0; i < rectChildren.Count; i++)
        {
            RectTransform child = rectChildren[i];
            SetChildAlongAxis(child, 0, childPositions[i].x, LayoutUtility.GetPreferredWidth(child));
            SetChildAlongAxis(child, 1, childPositions[i].y, LayoutUtility.GetPreferredHeight(child));
        }
    }

    private void calculatePositionsAndRequiredSize()
    {
        childPositions = new Vector2[rectChildren.Count];

        Vector2 startOffset = new Vector2(
            GetStartOffset(0, 0),
            GetStartOffset(1, 0)
        );

        Vector2 currentOffset = new Vector2(
            startOffset.x,
            startOffset.y
        );

        float childHeight = 0;
        float childWidth = 0;
        float maxChildHeightInRow = 0;

        int currentRow = 1;

        for (int i = 0; i < rectChildren.Count; i++)
        {
            childHeight = LayoutUtility.GetPreferredHeight(rectChildren[i]);
            childWidth = LayoutUtility.GetPreferredWidth(rectChildren[i]);

            //check for new row start
            if (currentOffset.x + spacing.x + childWidth > availableWidth && i != 0)
            {
                currentOffset.x = startOffset.x;
                currentOffset.y += maxChildHeightInRow + spacing.y;
                currentRow++;
                maxChildHeightInRow = 0;
            }

            childPositions[i] = new Vector2(
                currentOffset.x,
                currentOffset.y
            );

            //update offset
            maxChildHeightInRow = Mathf.Max(maxChildHeightInRow, childHeight);
            currentOffset.x += childWidth + spacing.x;

        }

        //update groups preferred dimensions
        preferredRows = currentRow;
        calculatedHeight = currentOffset.y + maxChildHeightInRow + padding.vertical - spacing.y;
    }
}

© www.soinside.com 2019 - 2024. All rights reserved.