public override void SetLayoutVertical()
        {
            HandleSelfFittingAndChildrenSizeAlongAxis(1);
            if (m_ProcessLayoutVertical)
            {
                return;
            }

            //对于高度限制的Item的设计,不要立刻派发布局完成,可能导致改变了宽度,需要重新计算
            //一般不要设置这个属性,会导致两遍计算
            if (m_NeedRecalculate)
            {
                m_ProcessLayoutVertical = true;
                LayoutRebuilderUtility.ForceRebuildLayoutImmediate(rectTransform);
            }

            if (m_LayoutGroupComplete != null)
            {
                m_ProcessLayoutVertical = false;
                m_LayoutGroupComplete.Invoke();
            }
        }
Example #2
0
        protected bool SetChildrenAlongAxis(bool isVertical)
        {
            for (int axis = 0; axis < 2; ++axis)
            {
                float size           = rectTransform.rect.size[axis];
                float startOffset    = -m_TopStartPosition;
                bool  alongOtherAxis = (isVertical ^ (axis == 1));
                if (alongOtherAxis)
                {
                    float innerSize = size;
                    startOffset = 0;
                    for (int i = 0; i < itemViewChildren.Count; i++)
                    {
                        var child    = itemViewChildren[i].ItemRectTransform;
                        var itemSize = LayoutUtility.GetPreferredSize(child, axis);
                        SetChildItemAlongAxis(child, axis, startOffset, innerSize);

                        if (!Mathf.Approximately(itemSize, innerSize))
                        {
                            LayoutRebuilderUtility.ForceRebuildLayoutImmediate(child);
                            return(true);
                        }
                    }
                }
                else
                {
                    for (int i = 0; i < itemViewChildren.Count; i++)
                    {
                        var child    = itemViewChildren[i].ItemRectTransform;
                        var itemSize = LayoutUtility.GetPreferredSize(child, axis);
                        SetChildItemAlongAxis(child, axis, startOffset, itemSize);
                        startOffset += itemSize + m_Divider;
                    }
                }
            }
            return(false);
        }
        private void HandleSelfFittingAndChildrenSizeAlongAxis(int axis)
        {
            FitMode fitting = (axis == 0 ? horizontalFit : verticalFit);

            if (fitting != FitMode.Unconstrained)
            {
                m_Tracker.Add(this, rectTransform,
                              (axis == 0 ? DrivenTransformProperties.SizeDeltaX : DrivenTransformProperties.SizeDeltaY));
                rectTransform.SetSizeWithCurrentAnchors((RectTransform.Axis)axis, GetTotalPreferredSize(axis));
            }

            SelfSizeRatioMode sizeRatioMode = (axis == 0 ? selfSizeWidthRatio : selfSizeHeightRatio);

            if (sizeRatioMode != SelfSizeRatioMode.Unconstrained)
            {
                bool needRebuild = false;

                if (sizeRatioMode == SelfSizeRatioMode.RelativeParent && rectTransform.parent != null &&
                    rectTransform.parent is RectTransform)
                {
                    //如果是限制在父对象内部,则限制的区域为
                    //父对象的宽和高减去limitPadding的水平和竖直间隔范围内
                    float preferred = LayoutUtility.GetPreferredSize(rectTransform.parent as RectTransform, axis) - (axis == 0 ? limitPadding.horizontal : limitPadding.vertical);
                    preferred = Mathf.Max(0, preferred);
                    preferred = axis == 0
                        ? Mathf.Clamp(GetTotalPreferredSize(axis), m_MinWidthRatio * preferred, m_MaxWidthRatio * preferred)
                        : Mathf.Clamp(GetTotalPreferredSize(axis), m_MinHeightRatio * preferred, m_MaxHeightRatio * preferred);

                    m_Tracker.Add(this, rectTransform,
                                  (axis == 0 ? DrivenTransformProperties.SizeDeltaX : DrivenTransformProperties.SizeDeltaY));

                    needRebuild = axis == 1 && (m_NeedRebuildCurrentFrame != Time.frameCount) && !Mathf.Approximately(preferred, GetTotalPreferredSize(1));

                    rectTransform.SetSizeWithCurrentAnchors((RectTransform.Axis)axis, preferred);
                    SetLayoutInputForAxis(preferred, preferred, -1, axis);
                }
                else if (sizeRatioMode == SelfSizeRatioMode.FixedSize)
                {
                    float preferred = (axis == 0 ? fixedSize.x: fixedSize.y) - (axis == 0 ? limitPadding.horizontal : limitPadding.vertical);
                    preferred = axis == 0
                                ? Mathf.Clamp(GetTotalPreferredSize(axis), m_MinWidthRatio * preferred, m_MaxWidthRatio * preferred)
                                : Mathf.Clamp(GetTotalPreferredSize(axis), m_MinHeightRatio * preferred, m_MaxHeightRatio * preferred);

                    m_Tracker.Add(this, rectTransform,
                                  (axis == 0 ? DrivenTransformProperties.SizeDeltaX : DrivenTransformProperties.SizeDeltaY));

                    needRebuild = axis == 1 && (m_NeedRebuildCurrentFrame != Time.frameCount) && !Mathf.Approximately(preferred, GetTotalPreferredSize(1));

                    rectTransform.SetSizeWithCurrentAnchors((RectTransform.Axis)axis, preferred);
                    SetLayoutInputForAxis(preferred, preferred, -1, axis);
                }

                if (needRebuild)
                {
                    //高度约束导致高度变化的情况下,需要重新计算布局,因为可能宽度也变了,但是宽度是提前算的,不重新算,会导致得到错误的值
                    m_NeedRebuildCurrentFrame = Time.frameCount;
                    LayoutRebuilderUtility.MarkLayoutForImmediateRebuild(rectTransform);
                    return;
                }
            }
        }
 public static bool IsRectTransformLayoutRebuild(RectTransform rectTransform)
 {
     return(!CanvasUpdateRegistry.TryRegisterCanvasElementForLayoutRebuild(LayoutRebuilderUtility.GetLayoutRebuilder(rectTransform)));
 }