///<summary> /// Utility to reconcile a desired size and state, with constraints imposed by a MeasureSpecification. ///</summary> /// <param name="size"> How big the layout wants to be.</param> /// <param name="measureSpecification"> Constraints imposed by the parent.</param> /// <param name="childMeasuredState"> Size information bit mask for the layout's children.</param> /// <returns> A measured size, which may indicate that it is too small. </returns> /// <since_tizen> 6 </since_tizen> protected MeasuredSize ResolveSizeAndState(LayoutLength size, MeasureSpecification measureSpecification, MeasuredSize.StateType childMeasuredState) { var specMode = measureSpecification.Mode; LayoutLength specSize = measureSpecification.Size; MeasuredSize result = new MeasuredSize(size, childMeasuredState); switch (specMode) { case MeasureSpecification.ModeType.AtMost: { if (specSize.AsRoundedValue() < size.AsRoundedValue()) { result = new MeasuredSize(specSize, MeasuredSize.StateType.MeasuredSizeTooSmall); } break; } case MeasureSpecification.ModeType.Exactly: { result.Size = specSize; break; } case MeasureSpecification.ModeType.Unspecified: default: { break; } } return(result); }
public void SetMeasuredDimensions(MeasuredSize measuredWidth, MeasuredSize measuredHeight) { LayoutPINVOKE.LayoutItemPtr_SetMeasuredDimensions(swigCPtr, MeasuredSize.getCPtr(measuredWidth), MeasuredSize.getCPtr(measuredHeight)); if (NDalicPINVOKE.SWIGPendingException.Pending) { throw NDalicPINVOKE.SWIGPendingException.Retrieve(); } }
public MeasuredSize GetMeasuredHeightAndState() { MeasuredSize ret = new MeasuredSize(LayoutPINVOKE.LayoutItemPtr_GetMeasuredHeightAndState(swigCPtr), true); if (NDalicPINVOKE.SWIGPendingException.Pending) { throw NDalicPINVOKE.SWIGPendingException.Retrieve(); } return(ret); }
private bool NotEqualTo(MeasuredSize value) { bool ret = LayoutPINVOKE.MeasuredSize_NotEqualTo(swigCPtr, MeasuredSize.getCPtr(value)); if (NDalicPINVOKE.SWIGPendingException.Pending) { throw NDalicPINVOKE.SWIGPendingException.Retrieve(); } return(ret); }
/// <summary> /// Measure the layout and its content to determine the measured width and the measured height.<br /> /// </summary> /// <param name="widthMeasureSpec">horizontal space requirements as imposed by the parent.</param> /// <param name="heightMeasureSpec">vertical space requirements as imposed by the parent.</param> /// <since_tizen> 6 </since_tizen> protected override void OnMeasure(MeasureSpecification widthMeasureSpec, MeasureSpecification heightMeasureSpec) { var gridWidthMode = widthMeasureSpec.Mode; var gridHeightMode = heightMeasureSpec.Mode; int widthSize = (int)widthMeasureSpec.Size.AsRoundedValue(); int heightSize = (int)heightMeasureSpec.Size.AsRoundedValue(); var childCount = LayoutChildren.Count; if (childCount > 0) { foreach (LayoutItem childLayout in LayoutChildren) { if (childLayout != null) { MeasureChild(childLayout, widthMeasureSpec, heightMeasureSpec); } } if (_GridOrientation == Orientation.Horizontal) { widthSize = CalculateHorizontalSize(gridWidthMode, gridHeightMode, widthSize, heightSize); heightSize = gridWidthMode == MeasureSpecification.ModeType.Exactly? heightSize: (int)(LayoutChildren[0].MeasuredHeight.Size.AsDecimal() + LayoutChildren[0].Margin.Top + LayoutChildren[0].Margin.Bottom) * Rows; } else { widthSize = gridWidthMode == MeasureSpecification.ModeType.Exactly? heightSize: (int)(LayoutChildren[0].MeasuredWidth.Size.AsDecimal() + LayoutChildren[0].Margin.Start + LayoutChildren[0].Margin.End) * Columns; heightSize = CalculateVerticalSize(gridWidthMode, gridHeightMode, widthSize, heightSize); } } // Children exists else { if (_GridOrientation == Orientation.Horizontal) { widthSize = (gridWidthMode == MeasureSpecification.ModeType.Unspecified)?0:widthSize; } else { heightSize = (gridHeightMode == MeasureSpecification.ModeType.Unspecified)?0:heightSize; } } LayoutLength widthLength = new LayoutLength(widthSize + Padding.Start + Padding.End); LayoutLength heightLenght = new LayoutLength(heightSize + Padding.Top + Padding.Bottom); MeasuredSize widthMeasuredSize = ResolveSizeAndState(widthLength, widthMeasureSpec, MeasuredSize.StateType.MeasuredSizeOK); MeasuredSize heightMeasuredSize = ResolveSizeAndState(heightLenght, heightMeasureSpec, MeasuredSize.StateType.MeasuredSizeOK); SetMeasuredDimensions(widthMeasuredSize, heightMeasuredSize); }
/// <summary> /// Determines whether the specified object is equal to the current object. /// </summary> /// <param name="obj">The object to compare with the current object.</param> /// <returns>true if the specified object is equal to the current object; otherwise, false.</returns> public override bool Equals(object obj) { MeasuredSize measuredSize = obj as MeasuredSize; bool equal = false; if (measuredSize != null) { if (Size == measuredSize.Size && State == measuredSize.State) { equal = true; } } return(equal); }
/// <summary> /// Measure the layout and its content to determine the measured width and the measured height.<br /> /// </summary> /// <param name="widthMeasureSpec">horizontal space requirements as imposed by the parent.</param> /// <param name="heightMeasureSpec">vertical space requirements as imposed by the parent.</param> /// <since_tizen> 6 </since_tizen> protected override void OnMeasure(MeasureSpecification widthMeasureSpec, MeasureSpecification heightMeasureSpec) { var gridWidthMode = widthMeasureSpec.Mode; var gridHeightMode = heightMeasureSpec.Mode; int widthSize = (int)widthMeasureSpec.Size.AsRoundedValue(); int heightSize = (int)heightMeasureSpec.Size.AsRoundedValue(); var childCount = LayoutChildren.Count; // WIDTH SPECIFICATIONS if (childCount > 0) { foreach (LayoutItem childLayout in LayoutChildren) { if (childLayout != null) { MeasureChild(childLayout, widthMeasureSpec, heightMeasureSpec); } } if (_linearOrientation == Orientation.Horizontal) { CalculateHorizontalSize(gridWidthMode, gridHeightMode, widthSize, heightSize); } else { CalculateVerticalSize(gridWidthMode, gridHeightMode, widthSize, heightSize); } } // Children exists LayoutLength widthLength = new LayoutLength(widthSize + Padding.Start + Padding.End); LayoutLength heightLenght = new LayoutLength(heightSize + Padding.Top + Padding.Bottom); MeasuredSize widthMeasuredSize = ResolveSizeAndState(widthLength, widthMeasureSpec, MeasuredSize.StateType.MeasuredSizeOK); MeasuredSize heightMeasuredSize = ResolveSizeAndState(heightLenght, heightMeasureSpec, MeasuredSize.StateType.MeasuredSizeOK); SetMeasuredDimensions(widthMeasuredSize, heightMeasuredSize); }
} // MeasureHorizontal private void MeasureVertical(MeasureSpecification widthMeasureSpec, MeasureSpecification heightMeasureSpec) { var widthMode = widthMeasureSpec.Mode; var heightMode = heightMeasureSpec.Mode; bool isExactly = (heightMode == MeasureSpecification.ModeType.Exactly); bool matchWidth = false; bool allFillParent = true; float maxWidth = 0.0f; float alternativeMaxWidth = 0.0f; float weightedMaxWidth = 0.0f; float totalWeight = 0.0f; int childrenCount = IterateLayoutChildren().Count(); // Reset total length _totalLength = 0.0f; float usedExcessSpace = 0.0f; HeightAndWidthState childState = new HeightAndWidthState(MeasuredSize.StateType.MeasuredSizeOK, MeasuredSize.StateType.MeasuredSizeOK); // measure children, and determine if further resolution is required // 1st phase: // We cycle through all children and measure children with weight 0 (non weighted children) according to their specs // to accumulate total used space in _totalLength. // Weighted children are not measured in this phase. // Available space for weighted children will be calculated in the phase 2 based on _totalLength value. foreach (LayoutItem childLayout in IterateLayoutChildren()) { childrenCount++; int childDesiredWidth = childLayout.Owner.WidthSpecification; float childWeight = childLayout.Owner.Weight; Extents childMargin = childLayout.Margin; totalWeight += childWeight; bool useExcessSpace = (childLayout.Owner.HeightSpecification == 0) && (childWeight > 0); if (isExactly && useExcessSpace) { _totalLength = Math.Max(_totalLength, (_totalLength + childMargin.Top + childMargin.Bottom)); } else { if (useExcessSpace) { // The heightMode is either Unspecified or AtMost, and // this child is only laid out using excess space. Measure // using WrapContent so that we can find out the view's // optimal height. // We'll restore the original height of 0 after measurement. MeasureSpecification childWidthMeasureSpec = GetChildMeasureSpecification( new MeasureSpecification( new LayoutLength(widthMeasureSpec.Size - (childLayout.Margin.Start + childLayout.Margin.End)), widthMeasureSpec.Mode), new LayoutLength(Padding.Start + Padding.End), new LayoutLength(childDesiredWidth)); MeasureSpecification childHeightMeasureSpec = GetChildMeasureSpecification( new MeasureSpecification( new LayoutLength(heightMeasureSpec.Size - (childLayout.Margin.Top + childLayout.Margin.Bottom)), heightMeasureSpec.Mode), new LayoutLength(Padding.Top + Padding.Bottom), new LayoutLength(LayoutParamPolicies.WrapContent)); childLayout.Measure(childWidthMeasureSpec, childHeightMeasureSpec); usedExcessSpace += childLayout.MeasuredHeight.Size.AsDecimal(); } else { MeasureChildWithMargins(childLayout, widthMeasureSpec, new LayoutLength(0), heightMeasureSpec, new LayoutLength(0)); } LayoutLength childHeight = childLayout.MeasuredHeight.Size; LayoutLength length = childHeight + childMargin.Top + childMargin.Bottom; _totalLength = Math.Max(_totalLength, _totalLength + length.AsDecimal()); } bool matchWidthLocally = false; if (widthMode != MeasureSpecification.ModeType.Exactly && childDesiredWidth == LayoutParamPolicies.MatchParent) { // Will have to re-measure at least this child when we know exact height. matchWidth = true; matchWidthLocally = true; } float marginWidth = childLayout.Margin.Start + childLayout.Margin.End; float childWidth = childLayout.MeasuredWidth.Size.AsDecimal() + marginWidth; if (childLayout.MeasuredWidth.State == MeasuredSize.StateType.MeasuredSizeTooSmall) { childState.widthState = MeasuredSize.StateType.MeasuredSizeTooSmall; } if (childLayout.MeasuredHeight.State == MeasuredSize.StateType.MeasuredSizeTooSmall) { childState.heightState = MeasuredSize.StateType.MeasuredSizeTooSmall; } maxWidth = Math.Max(maxWidth, childWidth); allFillParent = (allFillParent && childDesiredWidth == LayoutParamPolicies.MatchParent); if (childWeight > 0) { // Widths of weighted Views are bogus if we end up remeasuring, so keep them separate. weightedMaxWidth = Math.Max(weightedMaxWidth, matchWidthLocally ? marginWidth : childWidth); } else { alternativeMaxWidth = Math.Max(alternativeMaxWidth, matchWidthLocally ? marginWidth : childWidth); } } // foreach _totalLength = Math.Max(_totalLength, _totalLength + CellPadding.Height * (childrenCount - 1)); float heightSize = _totalLength; heightSize = Math.Max(heightSize, SuggestedMinimumHeight.AsDecimal()); MeasuredSize heightSizeAndState = ResolveSizeAndState(new LayoutLength(heightSize + Padding.Top + Padding.Bottom), heightMeasureSpec, MeasuredSize.StateType.MeasuredSizeOK); heightSize = heightSizeAndState.Size.AsDecimal(); // 2nd phase: // We cycle through weighted children now (children with weight > 0). // The children are measured with exact size equal to their share of the available space based on their weights. // _totalLength is updated to include weighted children measured sizes. float remainingExcess = heightSize - _totalLength + usedExcessSpace - (Padding.Top + Padding.Bottom); if (remainingExcess != 0 && totalWeight > 0.0f) { float remainingWeight = totalWeight; maxWidth = 0; _totalLength = 0; foreach (LayoutItem childLayout in IterateLayoutChildren()) { float desiredChildWidth = childLayout.Owner.WidthSpecification; float childWeight = childLayout.Owner.Weight; Extents childMargin = childLayout.Margin; if (childWeight > 0) { MeasureWeightedChild(childLayout, remainingExcess, remainingWeight, childWeight, widthMeasureSpec, heightMeasureSpec, childState, Orientation.Vertical); } float length = childLayout.MeasuredHeight.Size.AsDecimal() + childMargin.Top + childMargin.Bottom; _totalLength += length; bool matchWidthLocally = (widthMode != MeasureSpecification.ModeType.Exactly) && (desiredChildWidth == LayoutParamPolicies.MatchParent); float marginWidth = childMargin.Start + childMargin.End; float childWidth = childLayout.MeasuredWidth.Size.AsDecimal() + marginWidth; maxWidth = Math.Max(maxWidth, childWidth); alternativeMaxWidth = Math.Max(alternativeMaxWidth, matchWidthLocally ? marginWidth : childWidth); allFillParent = (allFillParent && desiredChildWidth == LayoutParamPolicies.MatchParent); } // for loop _totalLength = Math.Max(_totalLength, _totalLength + CellPadding.Height * (childrenCount - 1)); } else { alternativeMaxWidth = Math.Max(alternativeMaxWidth, weightedMaxWidth); } if (!allFillParent && widthMode != MeasureSpecification.ModeType.Exactly) { maxWidth = alternativeMaxWidth; } maxWidth += (Owner.WidthSpecification == LayoutParamPolicies.WrapContent) ? (Padding.Start + Padding.End) : 0; maxWidth = Math.Max(maxWidth, SuggestedMinimumWidth.AsRoundedValue()); heightSizeAndState.State = childState.heightState; SetMeasuredDimensions(ResolveSizeAndState(new LayoutLength(maxWidth), widthMeasureSpec, childState.widthState), heightSizeAndState); if (matchWidth) { ForceUniformWidth(heightMeasureSpec); } } // MeasureVertical
private void MeasureHorizontal(MeasureSpecification widthMeasureSpec, MeasureSpecification heightMeasureSpec) { var widthMode = widthMeasureSpec.Mode; var heightMode = heightMeasureSpec.Mode; bool isExactly = (widthMode == MeasureSpecification.ModeType.Exactly); bool matchHeight = false; bool allFillParent = true; float maxHeight = 0.0f; float alternativeMaxHeight = 0.0f; float weightedMaxHeight = 0.0f; float totalWeight = 0.0f; int childrenCount = IterateLayoutChildren().Count(); // Reset measure variables _totalLength = 0.0f; float usedExcessSpace = 0.0f; HeightAndWidthState childState = new HeightAndWidthState(MeasuredSize.StateType.MeasuredSizeOK, MeasuredSize.StateType.MeasuredSizeOK); // 1st phase: // We cycle through all children and measure children with weight 0 (non weighted children) according to their specs // to accumulate total used space in totalLength based on measured sizes and margins. // Weighted children are not measured at this phase. // Available space for weighted children will be calculated in the phase 2 based on totalLength value. // Max height of children is stored. foreach (LayoutItem childLayout in IterateLayoutChildren()) { int childDesiredHeight = childLayout.Owner.HeightSpecification; float childWeight = childLayout.Owner.Weight; Extents childMargin = childLayout.Margin; totalWeight += childWeight; bool useExcessSpace = (childLayout.Owner.WidthSpecification == 0) && (childWeight > 0); if (isExactly && useExcessSpace) { // Children to be laid out with excess space can be measured later _totalLength = Math.Max(_totalLength, (_totalLength + childMargin.Start + childMargin.End)); } else { if (useExcessSpace) { // Parent is not defiend!!! // The widthMode is either Unspecified or AtMost, and // this child is only laid out using excess space. Measure // using WrapContent so that we can find out the view's // optimal width. MeasureSpecification childWidthMeasureSpec = GetChildMeasureSpecification( new MeasureSpecification( new LayoutLength(widthMeasureSpec.Size - (childLayout.Margin.Start + childLayout.Margin.End)), widthMeasureSpec.Mode), new LayoutLength(Padding.Start + Padding.End), new LayoutLength(LayoutParamPolicies.WrapContent)); MeasureSpecification childHeightMeasureSpec = GetChildMeasureSpecification( new MeasureSpecification( new LayoutLength(heightMeasureSpec.Size - (childLayout.Margin.Top + childLayout.Margin.Bottom)), heightMeasureSpec.Mode), new LayoutLength(Padding.Top + Padding.Bottom), new LayoutLength(childDesiredHeight)); childLayout.Measure(childWidthMeasureSpec, childHeightMeasureSpec); usedExcessSpace += childLayout.MeasuredWidth.Size.AsDecimal(); } else { MeasureChildWithMargins(childLayout, widthMeasureSpec, new LayoutLength(0), heightMeasureSpec, new LayoutLength(0)); } LayoutLength childWidth = childLayout.MeasuredWidth.Size; LayoutLength length = childWidth + childMargin.Start + childMargin.End; _totalLength = Math.Max(_totalLength, _totalLength + length.AsDecimal()); } bool matchHeightLocally = false; if (heightMode != MeasureSpecification.ModeType.Exactly && childDesiredHeight == LayoutParamPolicies.MatchParent) { // A child has set to MatchParent on it's height. // Will have to re-measure at least this child when we know exact height. matchHeight = true; matchHeightLocally = true; } float marginHeight = childMargin.Top + childMargin.Bottom; float childHeight = childLayout.MeasuredHeight.Size.AsDecimal() + marginHeight; if (childLayout.MeasuredWidth.State == MeasuredSize.StateType.MeasuredSizeTooSmall) { childState.widthState = MeasuredSize.StateType.MeasuredSizeTooSmall; } if (childLayout.MeasuredHeight.State == MeasuredSize.StateType.MeasuredSizeTooSmall) { childState.heightState = MeasuredSize.StateType.MeasuredSizeTooSmall; } maxHeight = Math.Max(maxHeight, childHeight); allFillParent = (allFillParent && childDesiredHeight == LayoutParamPolicies.MatchParent); if (childWeight > 0) { // Heights of weighted Views are invalid if we end up remeasuring, so store them separately. weightedMaxHeight = Math.Max(weightedMaxHeight, matchHeightLocally ? marginHeight : childHeight); } else { alternativeMaxHeight = Math.Max(alternativeMaxHeight, matchHeightLocally ? marginHeight : childHeight); } } // foreach _totalLength = Math.Max(_totalLength, _totalLength + CellPadding.Width * (childrenCount - 1)); float widthSize = _totalLength; widthSize = Math.Max(widthSize, SuggestedMinimumWidth.AsDecimal()); MeasuredSize widthSizeAndState = ResolveSizeAndState(new LayoutLength(widthSize + Padding.Start + Padding.End), widthMeasureSpec, MeasuredSize.StateType.MeasuredSizeOK); widthSize = widthSizeAndState.Size.AsDecimal(); // 2nd phase: // Expand children with weight to take up available space // We cycle through weighted children now (children with weight > 0). // The children are measured with exact size equal to their share of the available space based on their weights. // _totalLength is updated to include weighted children measured sizes. float remainingExcess = widthSize - _totalLength + usedExcessSpace - (Padding.Start + Padding.End); if (remainingExcess != 0 && totalWeight > 0) { float remainingWeight = totalWeight; maxHeight = 0; _totalLength = 0; foreach (LayoutItem childLayout in IterateLayoutChildren()) { float desiredChildHeight = childLayout.Owner.HeightSpecification; float childWeight = childLayout.Owner.Weight; Extents childMargin = childLayout.Margin; if (childWeight > 0) { MeasureWeightedChild(childLayout, remainingExcess, remainingWeight, childWeight, widthMeasureSpec, heightMeasureSpec, childState, Orientation.Horizontal); } float length = childLayout.MeasuredWidth.Size.AsDecimal() + childMargin.Start + childMargin.End; _totalLength += length; bool matchHeightLocally = (heightMode != MeasureSpecification.ModeType.Exactly) && (desiredChildHeight == LayoutParamPolicies.MatchParent); float marginHeight = childMargin.Top + childMargin.Bottom; float childHeight = childLayout.MeasuredHeight.Size.AsDecimal() + marginHeight; maxHeight = Math.Max(maxHeight, childHeight); alternativeMaxHeight = Math.Max(alternativeMaxHeight, matchHeightLocally ? marginHeight : childHeight); allFillParent = (allFillParent && desiredChildHeight == LayoutParamPolicies.MatchParent); } // for loop _totalLength = Math.Max(_totalLength, _totalLength + CellPadding.Width * (childrenCount - 1)); } else { // No excess space or no weighted children alternativeMaxHeight = Math.Max(alternativeMaxHeight, weightedMaxHeight); } if (!allFillParent && heightMode != MeasureSpecification.ModeType.Exactly) { maxHeight = alternativeMaxHeight; } // Padding should be concerned when specification is Wrapcontent. maxHeight += (Owner.HeightSpecification == LayoutParamPolicies.WrapContent) ? (Padding.Top + Padding.Bottom) : 0; maxHeight = Math.Max(maxHeight, SuggestedMinimumHeight.AsRoundedValue()); widthSizeAndState.State = childState.widthState; SetMeasuredDimensions(widthSizeAndState, ResolveSizeAndState(new LayoutLength(maxHeight), heightMeasureSpec, childState.heightState)); if (matchHeight) { ForceUniformHeight(widthMeasureSpec); } } // MeasureHorizontal
} // MeasureHorizontal private void MeasureVertical(MeasureSpecification widthMeasureSpec, MeasureSpecification heightMeasureSpec) { var widthMode = widthMeasureSpec.Mode; var heightMode = heightMeasureSpec.Mode; bool isWidthExactly = (widthMode == MeasureSpecification.ModeType.Exactly); bool isHeightExactly = (heightMode == MeasureSpecification.ModeType.Exactly); float maxWidth = 0.0f; float totalWeight = 0.0f; int childrenCount = IterateLayoutChildren().Count(); // Child layout, which wants to match its height to its parent's remaining height, is either following 1 or 2. // 1. Child layout whose Owner.HeightSpecification is LayoutParamPolicies.MatchParent. // 2. Child layout whose Owner.HeightSpecification is 0 and Owner.Weight is greater than 0. // The number of child layout which wants to match its height to its parent's remaining height. int childrenMatchParentCount = 0; // Reset measure variable totalLength = 0.0f; HeightAndWidthState childState = new HeightAndWidthState(MeasuredSize.StateType.MeasuredSizeOK, MeasuredSize.StateType.MeasuredSizeOK); // 1ST PHASE: // // We measure all children whose height specification policy is WrapContent without weight. // After 1st phase, remaining height of parent is accumulated to calculate height of children // whose height specification policy is MatchParent. foreach (var childLayout in LayoutChildren) { if (!childLayout.SetPositionByLayout) { continue; } int childDesiredWidth = childLayout.Owner.WidthSpecification; int childDesiredHeight = childLayout.Owner.HeightSpecification; float childWeight = childLayout.Owner.Weight; Extents childMargin = childLayout.Margin; float childMarginWidth = childMargin.Start + childMargin.End; float childMarginHeight = childMargin.Top + childMargin.Bottom; bool useRemainingHeight = (childDesiredHeight == 0) && (childWeight > 0); if ((childDesiredHeight == LayoutParamPolicies.MatchParent) || (useRemainingHeight)) { totalWeight += childWeight; childrenMatchParentCount++; } // MatchParent child layout's margin is not added to totalLength. // Consequently, MatchParent child layout's margin is added to remaining size, // so the margin is not shared with other MatchParent child layouts. // e.g. // LinearLayout has size 100. // Child layout1 is MatchParent and its margin is 20. (This margin is not ad // Child layout2 is MatchParent and its margin is 0. // Then, child layout1's size is 30 and child layout2's size is 50. if ((childDesiredHeight == LayoutParamPolicies.WrapContent) || ((childDesiredHeight > 0) && (!useRemainingHeight))) { MeasureChildWithMargins(childLayout, widthMeasureSpec, new LayoutLength(0), heightMeasureSpec, new LayoutLength(0)); float childMeasuredHeight = childLayout.MeasuredHeight.Size.AsDecimal(); if (childMeasuredHeight < 0) { totalLength = Math.Max(totalLength, totalLength + childMarginHeight); } else { totalLength = Math.Max(totalLength, totalLength + childMeasuredHeight + childMarginHeight); } } if (childLayout.MeasuredWidth.State == MeasuredSize.StateType.MeasuredSizeTooSmall) { childState.widthState = MeasuredSize.StateType.MeasuredSizeTooSmall; } if (childLayout.MeasuredHeight.State == MeasuredSize.StateType.MeasuredSizeTooSmall) { childState.heightState = MeasuredSize.StateType.MeasuredSizeTooSmall; } float childMeasuredWidth = childLayout.MeasuredWidth.Size.AsDecimal(); if (childMeasuredWidth < 0) { maxWidth = Math.Max(maxWidth, childMarginWidth); } else { maxWidth = Math.Max(maxWidth, childMeasuredWidth + childMarginWidth); } } // 1ST PHASE foreach totalLength = Math.Max(totalLength, totalLength + CellPadding.Height * (childrenCount - 1) + Padding.Top + Padding.Bottom); float heightSize = Math.Max(totalLength, SuggestedMinimumHeight.AsDecimal()); MeasuredSize heightSizeAndState = ResolveSizeAndState(new LayoutLength(heightSize), heightMeasureSpec, MeasuredSize.StateType.MeasuredSizeOK); heightSize = heightSizeAndState.Size.AsDecimal(); float remainingHeight = heightSize - totalLength; float totalWeightLength = 0.0f; // Up to now, only WrapContent children's sizes are added to the totalLength. // Since the totalLength is used in OnLayout as the sum of all children's sizes, // the layout size is assigned to the totalLength if MatchParent child exists. if (childrenMatchParentCount > 0) { totalLength = heightSize; } // 2ND PHASE: // // We measure all children whose height specification policy is MatchParent without weight. // After 2nd phase, all children's heights are calculated without considering weight. // And the heights of all weighted children are accumulated to calculate weighted height. foreach (var childLayout in LayoutChildren) { if (!childLayout.SetPositionByLayout) { continue; } int childDesiredWidth = childLayout.Owner.WidthSpecification; int childDesiredHeight = childLayout.Owner.HeightSpecification; float childWeight = childLayout.Owner.Weight; Extents childMargin = childLayout.Margin; float childMarginWidth = childMargin.Start + childMargin.End; bool useRemainingHeight = (childDesiredHeight == 0) && (childWeight > 0); bool needToMeasure = false; if ((childDesiredWidth == LayoutParamPolicies.MatchParent) || (useRemainingHeight)) { if (isWidthExactly) { needToMeasure = true; } // RelativeLayout's MatchParent children should not fill to the RelativeLayout. // Because the children's sizes and positions are calculated by RelativeLayout's APIs. // Therefore, not to fill the RelativeLayout, the mode is changed from Exactly to AtMost. // // Not to print the recursive reference error message for this case, Specification is checked if it is WrapContent. else if (Owner.WidthSpecification == LayoutParamPolicies.WrapContent) { if (childDesiredWidth == LayoutParamPolicies.MatchParent) { Tizen.Log.Error("NUI", "There is a recursive reference! Parent layout(Owner: " + Owner + ")'s WidthSpecification is WrapContent and child layout(Owner: " + childLayout.Owner + ")'s WidthSpecification is MatchParent!"); } else { Tizen.Log.Error("NUI", "There is a recursive reference! Parent layout(Owner: " + Owner + ")'s WidthSpecification is WrapContent and child layout(Owner: " + childLayout.Owner + ")'s WidthSpecification is 0 with positive weight!"); } } } if (remainingHeight > 0) { if ((childDesiredHeight == LayoutParamPolicies.MatchParent) || (useRemainingHeight)) { if (isHeightExactly) { // In MeasureChildWithMargins(), it is assumed that heightMeasureSpec includes Padding.Top and Padding.Bottom. // Therefore, Padding.Top and Padding.Bottom are added to heightMeasureSpec.Size before it is passed to MeasureChildWithMargins(). heightMeasureSpec.SetSize(new LayoutLength((int)(remainingHeight / childrenMatchParentCount) + Padding.Top + Padding.Bottom)); needToMeasure = true; } // RelativeLayout's MatchParent children should not fill to the RelativeLayout. // Because the children's sizes and positions are calculated by RelativeLayout's APIs. // Therefore, not to fill the RelativeLayout, the mode is changed from Exactly to AtMost. // // Not to print the recursive reference error message for this case, Specification is checked if it is WrapContent. else if (Owner.HeightSpecification == LayoutParamPolicies.WrapContent) { if (childDesiredHeight == LayoutParamPolicies.MatchParent) { Tizen.Log.Error("NUI", "There is a recursive reference! Parent layout(Owner: " + Owner + ")'s HeightSpecification is WrapContent and child layout(Owner: " + childLayout.Owner + ")'s HeightSpecification is MatchParent!"); } else { Tizen.Log.Error("NUI", "There is a recursive reference! Parent layout(Owner: " + Owner + ")'s HeightSpecification is WrapContent and child layout(Owner: " + childLayout.Owner + ")'s HeightSpecification is 0 with positive weight!"); } } } } if (needToMeasure == true) { MeasureChildWithMargins(childLayout, widthMeasureSpec, new LayoutLength(0), heightMeasureSpec, new LayoutLength(0)); float childMeasuredWidth = childLayout.MeasuredWidth.Size.AsDecimal(); if (childMeasuredWidth < 0) { maxWidth = Math.Max(maxWidth, childMarginWidth); } else { maxWidth = Math.Max(maxWidth, childMeasuredWidth + childMarginWidth); } } if ((childWeight > 0) && ((childDesiredHeight == LayoutParamPolicies.MatchParent) || (childDesiredHeight == 0))) { float childMeasuredHeight = childLayout.MeasuredHeight.Size.AsDecimal(); if (childMeasuredHeight < 0) { totalWeightLength = Math.Max(totalWeightLength, totalWeightLength + childMargin.Top + childMargin.Bottom); } else { totalWeightLength = Math.Max(totalWeightLength, totalWeightLength + childMeasuredHeight + childMargin.Top + childMargin.Bottom); } } } // 2ND PHASE foreach // 3RD PHASE: // // We measure all weighted children whose owner has weight greater than 0. // After 3rd phase, all weighted children has height which is proportional to their weights // in remaining height of parent. if (totalWeight > 0) { foreach (var childLayout in LayoutChildren) { if (!childLayout.SetPositionByLayout) { continue; } int childDesiredHeight = childLayout.Owner.HeightSpecification; float childWeight = childLayout.Owner.Weight; if ((childWeight > 0) && ((childDesiredHeight == LayoutParamPolicies.MatchParent) || (childDesiredHeight == 0))) { if (isHeightExactly) { MeasureWeightedChild(childLayout, totalWeightLength, totalWeight, childWeight, widthMeasureSpec, heightMeasureSpec, childState, Orientation.Vertical); } // RelativeLayout's MatchParent children should not fill to the RelativeLayout. // Because the children's sizes and positions are calculated by RelativeLayout's APIs. // Therefore, not to fill the RelativeLayout, the mode is changed from Exactly to AtMost. // // Not to print the recursive reference error message for this case, Specification is checked if it is WrapContent. else if (Owner.HeightSpecification == LayoutParamPolicies.WrapContent) { if (childDesiredHeight == LayoutParamPolicies.MatchParent) { Tizen.Log.Error("NUI", "There is a recursive reference! Parent layout(Owner: " + Owner + ")'s HeightSpecification is WrapContent and child layout(Owner: " + childLayout.Owner + ")'s HeightSpecification is MatchParent!"); } else { Tizen.Log.Error("NUI", "There is a recursive reference! Parent layout(Owner: " + Owner + ")'s HeightSpecification is WrapContent and child layout(Owner: " + childLayout.Owner + ")'s HeightSpecification is 0 with positive weight!"); } } } } // 3RD PHASE foreach } maxWidth = Math.Max(maxWidth, maxWidth + (Padding.Start + Padding.End)); maxWidth = Math.Max(maxWidth, SuggestedMinimumWidth.AsRoundedValue()); heightSizeAndState.State = childState.heightState; SetMeasuredDimensions(ResolveSizeAndState(new LayoutLength(maxWidth), widthMeasureSpec, childState.widthState), heightSizeAndState); } // MeasureVertical
internal MeasuredSize GetMeasuredHeightAndState() { MeasuredSize ret = new MeasuredSize(LayoutPINVOKE.LayoutItemWrapperImpl_GetMeasuredHeightAndState(swigCPtr), true); if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve(); return ret; }
protected override void OnMeasure(MeasureSpecification widthMeasureSpec, MeasureSpecification heightMeasureSpec) { float totalHeight = 0.0f; float totalWidth = 0.0f; HeightAndWidthState childState = new HeightAndWidthState(MeasuredSize.StateType.MeasuredSizeOK, MeasuredSize.StateType.MeasuredSizeOK); float minPositionX = 0.0f; float minPositionY = 0.0f; float maxPositionX = 0.0f; float maxPositionY = 0.0f; // measure children foreach (LayoutItem childLayout in _children) { if (childLayout != null) { // Get size of child MeasureChild(childLayout, widthMeasureSpec, heightMeasureSpec); float childWidth = childLayout.MeasuredWidth.Size.AsDecimal(); float childHeight = childLayout.MeasuredHeight.Size.AsDecimal(); // Determine the width and height needed by the children using their given position and size. // Children could overlap so find the left most and right most child. Position2D childPosition = childLayout.Owner.Position2D; float childLeft = childPosition.X; float childTop = childPosition.Y; minPositionX = Math.Min(minPositionX, childLeft); maxPositionX = Math.Max(maxPositionX, childLeft + childWidth); // Children could overlap so find the highest and lowest child. minPositionY = Math.Min(minPositionY, childTop); maxPositionY = Math.Max(maxPositionY, childTop + childHeight); // Store current width and height needed to contain all children. totalWidth = maxPositionX - minPositionX; totalHeight = maxPositionY - minPositionY; if (childLayout.MeasuredWidthAndState.State == MeasuredSize.StateType.MeasuredSizeTooSmall) { childState.widthState = MeasuredSize.StateType.MeasuredSizeTooSmall; } if (childLayout.MeasuredWidthAndState.State == MeasuredSize.StateType.MeasuredSizeTooSmall) { childState.heightState = MeasuredSize.StateType.MeasuredSizeTooSmall; } } } MeasuredSize widthSizeAndState = ResolveSizeAndState(new LayoutLength(totalWidth), widthMeasureSpec, MeasuredSize.StateType.MeasuredSizeOK); MeasuredSize heightSizeAndState = ResolveSizeAndState(new LayoutLength(totalHeight), heightMeasureSpec, MeasuredSize.StateType.MeasuredSizeOK); totalWidth = widthSizeAndState.Size.AsDecimal(); totalHeight = heightSizeAndState.Size.AsDecimal(); // Ensure layout respects it's given minimum size totalWidth = Math.Max(totalWidth, SuggestedMinimumWidth.AsDecimal()); totalHeight = Math.Max(totalHeight, SuggestedMinimumHeight.AsDecimal()); widthSizeAndState.State = childState.widthState; heightSizeAndState.State = childState.heightState; SetMeasuredDimensions(ResolveSizeAndState(new LayoutLength(totalWidth), widthMeasureSpec, childState.widthState), ResolveSizeAndState(new LayoutLength(totalHeight), heightMeasureSpec, childState.heightState)); }
internal static global::System.Runtime.InteropServices.HandleRef getCPtr(MeasuredSize obj) { return((obj.Equals(null)) ? new global::System.Runtime.InteropServices.HandleRef(null, global::System.IntPtr.Zero) : obj.swigCPtr); }
} // MeasureHorizontally void MeasureVertical(MeasureSpecification widthMeasureSpec, MeasureSpecification heightMeasureSpec) { var widthMode = widthMeasureSpec.Mode; var heightMode = heightMeasureSpec.Mode; bool isExactly = (heightMode == MeasureSpecification.ModeType.Exactly); bool matchWidth = false; bool allFillParent = true; float maxWidth = 0.0f; float alternativeMaxWidth = 0.0f; float weightedMaxWidth = 0.0f; float totalWeight = 0.0f; // Reset total length _totalLength = 0.0f; LayoutLength usedExcessSpace = new LayoutLength(0); HeightAndWidthState childState = new HeightAndWidthState(MeasuredSize.StateType.MeasuredSizeOK, MeasuredSize.StateType.MeasuredSizeTooSmall); // measure children, and determine if further resolution is required // 1st phase: // We cycle through all children and measure children with weight 0 (non weighted children) according to their specs // to accumulate total used space in mTotalLength based on measured sizes and margins. // Weighted children are not measured at this phase. // Available space for weighted children will be calculated in the phase 2 based on mTotalLength value. uint index = 0; foreach (LayoutItem childLayout in _children) { LayoutLength childDesiredWidth = new LayoutLength(childLayout.Owner.WidthSpecification); LayoutLength childDesiredHeight = new LayoutLength(childLayout.Owner.HeightSpecification); float childWeight = childLayout.Owner.Weight; Extents childMargin = childLayout.Margin; totalWeight += childWeight; bool useExcessSpace = (childDesiredHeight.AsRoundedValue() == 0) && (childWeight > 0); if (isExactly && useExcessSpace) { LayoutLength totalLength = new LayoutLength(_totalLength); _totalLength = Math.Max(totalLength.AsDecimal(), (totalLength + childMargin.Top + childMargin.Bottom).AsDecimal()); } else { LayoutLength childHeight = new LayoutLength(0); if (useExcessSpace) { // The heightMode is either Unspecified or AtMost, and // this child is only laid out using excess space. Measure // using WrapContent so that we can find out the view's // optimal height. We'll restore the original height of 0 // after measurement. MeasureSpecification childWidthMeasureSpec = GetChildMeasureSpecification(widthMeasureSpec, new LayoutLength(childLayout.Padding.Start + childLayout.Padding.End), childDesiredWidth); MeasureSpecification childHeightMeasureSpec = GetChildMeasureSpecification(heightMeasureSpec, new LayoutLength(childLayout.Padding.Top + childLayout.Padding.Bottom), new LayoutLength(LayoutParamPolicies.WrapContent)); childLayout.Measure(childWidthMeasureSpec, childHeightMeasureSpec); childHeight = childLayout.MeasuredHeight.Size; usedExcessSpace += childHeight; } else { MeasureChild(childLayout, widthMeasureSpec, heightMeasureSpec); childHeight = childLayout.MeasuredHeight.Size; } float length = (childHeight + childMargin.Top + childMargin.Bottom).AsDecimal(); float cellPadding = CellPadding.Height; // No need to add cell padding to the end of last item. if (index >= _children.Count - 1) { cellPadding = 0.0f; } _totalLength = Math.Max(_totalLength, _totalLength + length + cellPadding); } bool matchWidthLocally = false; if (widthMode != MeasureSpecification.ModeType.Exactly && childDesiredWidth == new LayoutLength(LayoutParamPolicies.MatchParent)) { // Will have to re-measure at least this child when we know exact height. matchWidth = true; matchWidthLocally = true; } float marginWidth = (childLayout.Margin.Start) + (childLayout.Margin.End); LayoutLength childWidth = new LayoutLength(childLayout.MeasuredWidth.Size.AsDecimal() + marginWidth); // was combineMeasuredStates() if (childLayout.MeasuredWidthAndState.State == MeasuredSize.StateType.MeasuredSizeTooSmall) { childState.widthState = MeasuredSize.StateType.MeasuredSizeTooSmall; } if (childLayout.MeasuredHeightAndState.State == MeasuredSize.StateType.MeasuredSizeTooSmall) { childState.heightState = MeasuredSize.StateType.MeasuredSizeTooSmall; } maxWidth = (Math.Max(maxWidth, childWidth.AsDecimal())); allFillParent = (allFillParent && (childDesiredWidth == new LayoutLength(LayoutParamPolicies.MatchParent))); float widthforWeight = childWidth.AsDecimal(); if (matchWidthLocally) { widthforWeight = marginWidth; } if (childWeight > 0) { /* * Widths of weighted Views are bogus if we end up remeasuring, so keep them separate. */ weightedMaxWidth = Math.Max(weightedMaxWidth, widthforWeight); } else { alternativeMaxWidth = Math.Max(alternativeMaxWidth, widthforWeight); } } // foreach Extents padding = Padding; _totalLength += padding.Top + padding.Bottom; LayoutLength heightSize = new LayoutLength(_totalLength); heightSize = new LayoutLength(Math.Max(heightSize.AsDecimal(), SuggestedMinimumHeight.AsDecimal())); MeasuredSize heightSizeAndState = ResolveSizeAndState(heightSize, heightMeasureSpec, MeasuredSize.StateType.MeasuredSizeOK); heightSize = heightSizeAndState.Size; // Either expand children with weight to take up available space or // shrink them if they extend beyond our current bounds. If we skipped // measurement on any children, we need to measure them now. // 2nd phase: // We cycle through weighted children now (children with weight > 0). // The children are measured with exact size equal to their share of the available space based on their weights. // TotalLength is updated to include weighted children measured sizes. float remainingExcess = heightSize.AsDecimal() - _totalLength + usedExcessSpace.AsDecimal(); if (remainingExcess != 0 && totalWeight > 0.0f) { float remainingWeightSum = totalWeight; _totalLength = 0; foreach (LayoutItem childLayout in _children) { int desiredWidth = childLayout.Owner.WidthSpecification; int desiredHeight = childLayout.Owner.HeightSpecification; float childWeight = childLayout.Owner.Weight; Extents childMargin = childLayout.Margin; float childHeight = 0; if (childWeight > 0) { float share = (childWeight * remainingExcess) / remainingWeightSum; remainingExcess -= share; remainingWeightSum -= childWeight; // Always lay out weighted elements with intrinsic size regardless of the parent spec // for consistency between specs. if (desiredHeight == 0) { // This child needs to be laid out from scratch using // only its share of excess space. childHeight = share; } else { // This child had some intrinsic width to which we // need to add its share of excess space. childHeight = childLayout.MeasuredHeight.Size.AsDecimal() + share; } MeasureSpecification childWidthMeasureSpec = GetChildMeasureSpecification(widthMeasureSpec, new LayoutLength(Padding.Start + Padding.End), new LayoutLength(desiredWidth)); MeasureSpecification childHeightMeasureSpec = new MeasureSpecification(new LayoutLength(childHeight), MeasureSpecification.ModeType.Exactly); childLayout.Measure(childWidthMeasureSpec, childHeightMeasureSpec); // Child may now not fit in vertical dimension. if (childLayout.MeasuredHeightAndState.State == MeasuredSize.StateType.MeasuredSizeTooSmall) { childState.heightState = MeasuredSize.StateType.MeasuredSizeTooSmall; } } bool matchWidthLocally = false; if (widthMode != MeasureSpecification.ModeType.Exactly && desiredWidth == (int)ChildLayoutData.MatchParent) { // Will have to re-measure at least this child when we know exact height. matchWidth = true; matchWidthLocally = true; } float marginWidth = childMargin.Start + childMargin.End; float childWidth = childLayout.MeasuredWidth.Size.AsDecimal() + marginWidth; maxWidth = Math.Max(maxWidth, childWidth); allFillParent = allFillParent && desiredWidth == (int)ChildLayoutData.MatchParent; alternativeMaxWidth = Math.Max(alternativeMaxWidth, matchWidthLocally ? marginWidth : childWidth); childHeight = childLayout.MeasuredHeight.Size.AsDecimal(); float length = childHeight + childMargin.Top + childMargin.Bottom; float cellPadding = CellPadding.Height; // No need to add cell padding to the end of last item. if (index >= _children.Count - 1) { cellPadding = 0.0f; } _totalLength = Math.Max(_totalLength, _totalLength + length + cellPadding); } // foreach // Add in our padding _totalLength += Padding.Top + Padding.Bottom; } else { alternativeMaxWidth = Math.Max(alternativeMaxWidth, weightedMaxWidth); } if (!allFillParent && widthMode != MeasureSpecification.ModeType.Exactly) { maxWidth = alternativeMaxWidth; } maxWidth += padding.Start + padding.End; maxWidth = Math.Max(maxWidth, SuggestedMinimumWidth.AsRoundedValue()); heightSizeAndState.State = childState.heightState; SetMeasuredDimensions(ResolveSizeAndState(new LayoutLength(maxWidth), widthMeasureSpec, childState.widthState), heightSizeAndState); if (matchWidth) { ForceUniformWidth(_children.Count, heightMeasureSpec); } } // MeasureVertically
protected void SetMeasuredDimensions(MeasuredSize measuredWidth, MeasuredSize measuredHeight) { layoutItemWrapperImpl.SetMeasuredDimensions(measuredWidth, measuredHeight); }
/// <summary> /// This method must be called by OnMeasure(MeasureSpec,MeasureSpec) to store the measured width and measured height. /// </summary> /// <param name="measuredWidth">The measured width of this layout.</param> /// <param name="measuredHeight">The measured height of this layout.</param> /// <since_tizen> 6 </since_tizen> protected void SetMeasuredDimensions(MeasuredSize measuredWidth, MeasuredSize measuredHeight) { MeasuredWidth = measuredWidth; MeasuredHeight = measuredHeight; Flags = Flags | LayoutFlags.MeasuredDimensionSet; }
private void MeasureHorizontal(MeasureSpecification widthMeasureSpec, MeasureSpecification heightMeasureSpec) { var widthMode = widthMeasureSpec.Mode; var heightMode = heightMeasureSpec.Mode; bool isExactly = (widthMode == MeasureSpecification.ModeType.Exactly); bool matchHeight = false; bool allFillParent = true; float maxHeight = 0.0f; float alternativeMaxHeight = 0.0f; float weightedMaxHeight = 0.0f; float totalWeight = 0.0f; // Reset total length _totalLength = 0.0f; LayoutLength usedExcessSpace = new LayoutLength(0); HeightAndWidthState childState = new HeightAndWidthState(MeasuredSize.StateType.MeasuredSizeOK, MeasuredSize.StateType.MeasuredSizeOK); // Measure children, and determine if further resolution is required // 1st phase: // We cycle through all children and measure children with weight 0 (non weighted children) according to their specs // to accumulate total used space in totalLength based on measured sizes and margins. // Weighted children are not measured at this phase. // Available space for weighted children will be calculated in the phase 2 based on totalLength value. foreach (LayoutItem childLayout in _children) { LayoutLength childDesiredWidth = new LayoutLength(childLayout.Owner.WidthSpecification); LayoutLength childDesiredHeight = new LayoutLength(childLayout.Owner.HeightSpecification); float childWeight = childLayout.Owner.Weight; Extents childMargin = childLayout.Margin; totalWeight += childWeight; bool useExcessSpace = (childDesiredWidth.AsRoundedValue() == 0) && (childWeight > 0); if (isExactly && useExcessSpace) { _totalLength += childMargin.Start + childMargin.End; } else { if (useExcessSpace) { // The widthMode is either UNSPECIFIED or AT_MOST, and // this child is only laid out using excess space. Measure // using WRAP_CONTENT so that we can find out the view's // optimal width. MeasureSpecification childWidthMeasureSpec = GetChildMeasureSpecification(widthMeasureSpec, new LayoutLength(childLayout.Padding.Start + childLayout.Padding.End), new LayoutLength(LayoutParamPolicies.WrapContent)); MeasureSpecification childHeightMeasureSpec = GetChildMeasureSpecification(heightMeasureSpec, new LayoutLength(childLayout.Padding.Top + childLayout.Padding.Bottom), childDesiredHeight); childLayout.Measure(childWidthMeasureSpec, childHeightMeasureSpec); usedExcessSpace += childLayout.MeasuredWidth.Size; } else { MeasureChild(childLayout, widthMeasureSpec, heightMeasureSpec); } LayoutLength childWidth = childLayout.MeasuredWidth.Size; LayoutLength length = childWidth + childMargin.Start + childMargin.End; if (isExactly) { _totalLength += length.AsDecimal(); } else { _totalLength = Math.Max(_totalLength, _totalLength + length.AsDecimal() + CellPadding.Width); } } bool matchHeightLocally = false; if (heightMode != MeasureSpecification.ModeType.Exactly && (int)childDesiredHeight.AsRoundedValue() == LayoutParamPolicies.MatchParent) { // Will have to re-measure at least this child when we know exact height. matchHeight = true; matchHeightLocally = true; } LayoutLength marginHeight = new LayoutLength(childMargin.Top + childMargin.Bottom); LayoutLength childHeight = childLayout.MeasuredHeight.Size + marginHeight; if (childLayout.MeasuredWidthAndState.State == MeasuredSize.StateType.MeasuredSizeTooSmall) { childState.widthState = MeasuredSize.StateType.MeasuredSizeTooSmall; } if (childLayout.MeasuredHeightAndState.State == MeasuredSize.StateType.MeasuredSizeTooSmall) { childState.heightState = MeasuredSize.StateType.MeasuredSizeTooSmall; } maxHeight = Math.Max(maxHeight, childHeight.AsDecimal()); allFillParent = (allFillParent && childDesiredHeight.AsRoundedValue() == LayoutParamPolicies.MatchParent); if (childWeight > 0) { /* * Heights of weighted Views are bogus if we end up * remeasuring, so keep them separate. */ weightedMaxHeight = Math.Max(weightedMaxHeight, matchHeightLocally ? marginHeight.AsDecimal() : childHeight.AsDecimal()); } else { alternativeMaxHeight = Math.Max(alternativeMaxHeight, matchHeightLocally ? marginHeight.AsDecimal() : childHeight.AsDecimal()); } } // foreach Extents padding = Padding; _totalLength += padding.Start + padding.End; LayoutLength widthSize = new LayoutLength(_totalLength); widthSize = new LayoutLength(Math.Max(widthSize.AsDecimal(), SuggestedMinimumWidth.AsDecimal())); MeasuredSize widthSizeAndState = ResolveSizeAndState(widthSize, widthMeasureSpec, MeasuredSize.StateType.MeasuredSizeOK); widthSize = widthSizeAndState.Size; if (!allFillParent && heightMode != MeasureSpecification.ModeType.Exactly) { maxHeight = alternativeMaxHeight; } maxHeight += padding.Top + padding.Bottom; maxHeight = Math.Max(maxHeight, SuggestedMinimumHeight.AsRoundedValue()); widthSizeAndState.State = childState.widthState; SetMeasuredDimensions(widthSizeAndState, ResolveSizeAndState(new LayoutLength(maxHeight), heightMeasureSpec, childState.heightState)); if (matchHeight) { ForceUniformHeight(_children.Count, widthMeasureSpec); } } // MeasureHorizontally