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(); } }
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))); }