protected override void OnMeasure(MeasureSpecification widthMeasureSpec, MeasureSpecification heightMeasureSpec) { MeasuredSize.StateType childWidthState = MeasuredSize.StateType.MeasuredSizeOK; MeasuredSize.StateType childHeightState = MeasuredSize.StateType.MeasuredSizeOK; for (int i = 0; i < LayoutChildren.Count; i++) { LayoutItem childLayout = LayoutChildren[i]; if (childLayout != null) { MeasureChildWithMargins(childLayout, widthMeasureSpec, new LayoutLength(0), heightMeasureSpec, new LayoutLength(0)); if (childLayout.MeasuredWidth.State == MeasuredSize.StateType.MeasuredSizeTooSmall) { childWidthState = MeasuredSize.StateType.MeasuredSizeTooSmall; } if (childLayout.MeasuredHeight.State == MeasuredSize.StateType.MeasuredSizeTooSmall) { childHeightState = MeasuredSize.StateType.MeasuredSizeTooSmall; } } } (float childrenWidth, float childrenHeight) = CalculateChildrenSize(widthMeasureSpec.Size.AsDecimal(), heightMeasureSpec.Size.AsDecimal()); SetMeasuredDimensions(ResolveSizeAndState(new LayoutLength(childrenWidth), widthMeasureSpec, childWidthState), ResolveSizeAndState(new LayoutLength(childrenHeight), heightMeasureSpec, childHeightState)); }
public MeasuredSize(LayoutLength measuredSize, MeasuredSize.StateType state) : this(LayoutPINVOKE.new_MeasuredSize__SWIG_2(LayoutLength.getCPtr(measuredSize), (int)state), true) { if (NDalicPINVOKE.SWIGPendingException.Pending) { throw NDalicPINVOKE.SWIGPendingException.Retrieve(); } }
private void SetState(MeasuredSize.StateType state) { LayoutPINVOKE.MeasuredSize_SetState(swigCPtr, (int)state); if (NDalicPINVOKE.SWIGPendingException.Pending) { throw NDalicPINVOKE.SWIGPendingException.Retrieve(); } }
private MeasuredSize.StateType GetState() { MeasuredSize.StateType ret = (MeasuredSize.StateType)LayoutPINVOKE.MeasuredSize_GetState(swigCPtr); if (NDalicPINVOKE.SWIGPendingException.Pending) { throw NDalicPINVOKE.SWIGPendingException.Retrieve(); } return(ret); }
protected override void OnMeasure(MeasureSpecification widthMeasureSpec, MeasureSpecification heightMeasureSpec) { float maxWidth = SuggestedMinimumWidth.AsDecimal(); float maxHeight = SuggestedMinimumHeight.AsDecimal(); MeasuredSize.StateType childWidthState = MeasuredSize.StateType.MeasuredSizeOK; MeasuredSize.StateType childHeightState = MeasuredSize.StateType.MeasuredSizeOK; var appBar = (Owner as ContentPage)?.AppBar; var content = (Owner as ContentPage)?.Content; foreach (var childLayout in LayoutChildren) { if (!childLayout.SetPositionByLayout) { continue; } if ((content != null) && (content == childLayout.Owner) && (content.HeightSpecification == LayoutParamPolicies.MatchParent)) { var contentSizeH = heightMeasureSpec.Size.AsDecimal() - Padding.Top - Padding.Bottom - content.Margin.Top - content.Margin.Bottom - (appBar?.Layout.MeasuredHeight.Size.AsDecimal() ?? 0); MeasureSpecification contentHeightSpec = new MeasureSpecification(new LayoutLength(contentSizeH), MeasureSpecification.ModeType.Exactly); MeasureChildWithoutPadding(childLayout, widthMeasureSpec, contentHeightSpec); } else { MeasureChildWithoutPadding(childLayout, widthMeasureSpec, heightMeasureSpec); } float childRight = childLayout.MeasuredWidth.Size.AsDecimal() + childLayout.Owner.PositionX; float childBottom = childLayout.MeasuredHeight.Size.AsDecimal() + childLayout.Owner.PositionY; if (maxWidth < childRight) { maxWidth = childRight; } if (maxHeight < childBottom) { maxHeight = childBottom; } if (childLayout.MeasuredWidth.State == MeasuredSize.StateType.MeasuredSizeTooSmall) { childWidthState = MeasuredSize.StateType.MeasuredSizeTooSmall; } if (childLayout.MeasuredHeight.State == MeasuredSize.StateType.MeasuredSizeTooSmall) { childHeightState = MeasuredSize.StateType.MeasuredSizeTooSmall; } } SetMeasuredDimensions(ResolveSizeAndState(new LayoutLength(maxWidth), widthMeasureSpec, childWidthState), ResolveSizeAndState(new LayoutLength(maxHeight), heightMeasureSpec, childHeightState)); }
/// <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) { // Ensure layout respects it's given minimum size float maxWidth = SuggestedMinimumWidth.AsDecimal(); float maxHeight = SuggestedMinimumHeight.AsDecimal(); MeasuredSize.StateType childWidthState = MeasuredSize.StateType.MeasuredSizeOK; MeasuredSize.StateType childHeightState = MeasuredSize.StateType.MeasuredSizeOK; for (int i = 0; i < LayoutChildren.Count; i++) { LayoutItem childLayout = LayoutChildren[i]; if (childLayout != null) { // Get size of child with no padding, no margin. we won't support margin, padding for AbsolutLayout. MeasureChildWithoutPadding(childLayout, widthMeasureSpec, heightMeasureSpec); if (childLayout.Owner.ExcludeLayouting) { continue; } // Determine the width and height needed by the children using their given position and size. // Children could overlap so find the right most child. Position2D childPosition = childLayout.Owner.Position2D; float childRight = childLayout.MeasuredWidth.Size.AsDecimal() + childPosition.X; float childBottom = childLayout.MeasuredHeight.Size.AsDecimal() + childPosition.Y; if (maxWidth < childRight) { maxWidth = childRight; } if (maxHeight < childBottom) { maxHeight = childBottom; } if (childLayout.MeasuredWidth.State == MeasuredSize.StateType.MeasuredSizeTooSmall) { childWidthState = MeasuredSize.StateType.MeasuredSizeTooSmall; } if (childLayout.MeasuredHeight.State == MeasuredSize.StateType.MeasuredSizeTooSmall) { childHeightState = MeasuredSize.StateType.MeasuredSizeTooSmall; } } } SetMeasuredDimensions(ResolveSizeAndState(new LayoutLength(maxWidth), widthMeasureSpec, childWidthState), ResolveSizeAndState(new LayoutLength(maxHeight), heightMeasureSpec, childHeightState)); }
protected override void OnMeasure(MeasureSpecification widthMeasureSpec, MeasureSpecification heightMeasureSpec) { // Padding will be automatically applied by DALi TextLabel. float totalWidth = widthMeasureSpec.Size.AsDecimal(); float totalHeight = heightMeasureSpec.Size.AsDecimal(); if (widthMeasureSpec.Mode == MeasureSpecification.ModeType.Exactly) { if (heightMeasureSpec.Mode != MeasureSpecification.ModeType.Exactly) { totalHeight = Owner.GetHeightForWidth(totalWidth); heightMeasureSpec = new MeasureSpecification(new LayoutLength(totalHeight), MeasureSpecification.ModeType.Exactly); } } else { var minSize = Owner.MinimumSize; var maxSize = Owner.MaximumSize; var naturalSize = Owner.GetNaturalSize(); if (heightMeasureSpec.Mode == MeasureSpecification.ModeType.Exactly) { // GetWidthForHeight is not implemented. totalWidth = Math.Min(Math.Max(naturalSize.Width, minSize.Width), (maxSize.Width < 0 ? Int32.MaxValue : maxSize.Width)); widthMeasureSpec = new MeasureSpecification(new LayoutLength(totalWidth), MeasureSpecification.ModeType.Exactly); } else { totalWidth = Math.Min(Math.Max(naturalSize.Width, minSize.Width), (maxSize.Width < 0 ? Int32.MaxValue : maxSize.Width)); totalHeight = Math.Min(Math.Max(naturalSize.Height, minSize.Height), (maxSize.Height < 0 ? Int32.MaxValue : maxSize.Height)); heightMeasureSpec = new MeasureSpecification(new LayoutLength(totalHeight), MeasureSpecification.ModeType.Exactly); widthMeasureSpec = new MeasureSpecification(new LayoutLength(totalWidth), MeasureSpecification.ModeType.Exactly); } } MeasuredSize.StateType childWidthState = MeasuredSize.StateType.MeasuredSizeOK; MeasuredSize.StateType childHeightState = MeasuredSize.StateType.MeasuredSizeOK; SetMeasuredDimensions(ResolveSizeAndState(new LayoutLength(totalWidth), widthMeasureSpec, childWidthState), ResolveSizeAndState(new LayoutLength(totalHeight), heightMeasureSpec, childHeightState)); }
protected override void OnMeasure(MeasureSpecification widthMeasureSpec, MeasureSpecification heightMeasureSpec) { // Padding will be automatically applied by DALi TextLabel. float totalWidth = widthMeasureSpec.Size.AsDecimal(); float totalHeight = heightMeasureSpec.Size.AsDecimal(); if (widthMeasureSpec.Mode == MeasureSpecification.ModeType.Exactly) { if (heightMeasureSpec.Mode != MeasureSpecification.ModeType.Exactly) { totalHeight = Owner.GetHeightForWidth(totalWidth); heightMeasureSpec = new MeasureSpecification(new LayoutLength(totalHeight), MeasureSpecification.ModeType.Exactly); } } else { if (heightMeasureSpec.Mode == MeasureSpecification.ModeType.Exactly) { // GetWidthForHeight is not implemented. totalWidth = Owner.GetNaturalSize().Width; widthMeasureSpec = new MeasureSpecification(new LayoutLength(totalWidth), MeasureSpecification.ModeType.Exactly); } else { Vector3 naturalSize = Owner.GetNaturalSize(); totalWidth = naturalSize.Width; totalHeight = naturalSize.Height; heightMeasureSpec = new MeasureSpecification(new LayoutLength(totalHeight), MeasureSpecification.ModeType.Exactly); widthMeasureSpec = new MeasureSpecification(new LayoutLength(totalWidth), MeasureSpecification.ModeType.Exactly); } } MeasuredSize.StateType childWidthState = MeasuredSize.StateType.MeasuredSizeOK; MeasuredSize.StateType childHeightState = MeasuredSize.StateType.MeasuredSizeOK; SetMeasuredDimensions(ResolveSizeAndState(new LayoutLength(totalWidth), widthMeasureSpec, childWidthState), ResolveSizeAndState(new LayoutLength(totalHeight), heightMeasureSpec, childHeightState)); }
///<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 HeightAndWidthState(MeasuredSize.StateType width, MeasuredSize.StateType height) { widthState = width; heightState = height; }
protected override void OnMeasure(MeasureSpecification widthMeasureSpec, MeasureSpecification heightMeasureSpec) { Extents padding = Padding; float totalHeight = padding.Top + padding.Bottom; float totalWidth = padding.Start + padding.End; MeasuredSize.StateType childWidthState = MeasuredSize.StateType.MeasuredSizeOK; MeasuredSize.StateType childHeightState = MeasuredSize.StateType.MeasuredSizeOK; Direction scrollingDirection = Direction.Vertical; ScrollableBase scrollableBase = this.Owner as ScrollableBase; if (scrollableBase) { scrollingDirection = scrollableBase.ScrollingDirection; } // measure child, should be a single scrolling child foreach (LayoutItem childLayout in LayoutChildren) { if (childLayout != null) { // Get size of child // Use an Unspecified MeasureSpecification mode so scrolling child is not restricted to it's parents size in Height (for vertical scrolling) // or Width for horizontal scrolling MeasureSpecification unrestrictedMeasureSpec = new MeasureSpecification(heightMeasureSpec.Size, MeasureSpecification.ModeType.Unspecified); if (scrollingDirection == Direction.Vertical) { MeasureChild(childLayout, widthMeasureSpec, unrestrictedMeasureSpec); // Height unrestricted by parent } else { MeasureChild(childLayout, unrestrictedMeasureSpec, heightMeasureSpec); // Width unrestricted by parent } 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; // Store current width and height needed to contain all children. Extents childMargin = childLayout.Margin; totalWidth = childWidth + childMargin.Start + childMargin.End; totalHeight = childHeight + childMargin.Top + childMargin.Bottom; if (childLayout.MeasuredWidth.State == MeasuredSize.StateType.MeasuredSizeTooSmall) { childWidthState = MeasuredSize.StateType.MeasuredSizeTooSmall; } if (childLayout.MeasuredWidth.State == MeasuredSize.StateType.MeasuredSizeTooSmall) { childHeightState = 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 = childWidthState; heightSizeAndState.State = childHeightState; SetMeasuredDimensions(ResolveSizeAndState(new LayoutLength(totalWidth), widthMeasureSpec, childWidthState), ResolveSizeAndState(new LayoutLength(totalHeight), heightMeasureSpec, childHeightState)); }
/// <inheritdoc/> /// <since_tizen> 9 </since_tizen> protected override void OnMeasure(MeasureSpecification widthMeasureSpec, MeasureSpecification heightMeasureSpec) { MeasuredSize.StateType childWidthState = MeasuredSize.StateType.MeasuredSizeOK; MeasuredSize.StateType childHeightState = MeasuredSize.StateType.MeasuredSizeOK; for (int i = 0; i < LayoutChildren.Count; i++) { LayoutItem childLayout = LayoutChildren[i]; if (childLayout != null) { MeasureChildWithMargins(childLayout, widthMeasureSpec, new LayoutLength(0), heightMeasureSpec, new LayoutLength(0)); if (childLayout.MeasuredWidth.State == MeasuredSize.StateType.MeasuredSizeTooSmall) { childWidthState = MeasuredSize.StateType.MeasuredSizeTooSmall; } if (childLayout.MeasuredHeight.State == MeasuredSize.StateType.MeasuredSizeTooSmall) { childHeightState = MeasuredSize.StateType.MeasuredSizeTooSmall; } } } (float childrenWidth, float childrenHeight) = CalculateChildrenSize(widthMeasureSpec.Size.AsDecimal(), heightMeasureSpec.Size.AsDecimal()); SetMeasuredDimensions(ResolveSizeAndState(new LayoutLength(childrenWidth), widthMeasureSpec, childWidthState), ResolveSizeAndState(new LayoutLength(childrenHeight), heightMeasureSpec, childHeightState)); // There are 2 cases which require to calculate children's MeasuredWidth/Height as follows. // // 1. Text with Ellipsis true // TextLabel and TextField calculate MeasuredWidth/Height to cover their text string if they have WrapContent. // This causes children's Ellipsis cannot be displayed with RelativeLayout. // To resolve the above, RelativeLayout recalculates its children's MeasuredWidth/Height based on the children's space calculated by RelativeLayout APIs. // // 2. FillHorizontal/Vertical true // If children set FillHorizontal/Vertical true, then children's MeasuredWidth/Height are not correctly alculated. // Instead, children's size and position are correctly calculated in OnLayout(). // This causes that the grand children's MeasuredWidth/Height are calculated incorrectly. // To resolve the above, RelativeLayout calculates its children's MeasuredWidth/Height based on the children's geometry calculated by RelativeLayout APIs. // // e.g. // Let parent have RelativeLayout and parent's size be 1920x1080. // Let child have WrapContent with SetFillHorizontal/Vertical true. // Let grand child have MatchParent. // Then, child's size is 1920x1080 but child's MeasuredWidth/Height is 0x0. // Then, grand child's MeasuredWidth/Height is 0x0 and size is 0x0. // // TODO: Not to do duplicate operations in OnLayout() again. bool needClearCache = false; for (int i = 0; i < LayoutChildren.Count; i++) { LayoutItem childLayout = LayoutChildren[i]; if (childLayout != null) { bool ellipsisTextWidth = false; bool ellipsisTextHeight = false; bool needMeasuredWidth = false; bool needMeasuredHeight = false; if (((childLayout.Owner is TextLabel textLabel) && textLabel.Ellipsis) || ((childLayout.Owner is TextField textField) && textField.Ellipsis)) { Geometry horizontalSpace = GetHorizontalSpace(childLayout.Owner); if (!horizontalSpace.Size.Equals(0)) { ellipsisTextWidth = true; needClearCache = true; } Geometry verticalSpace = GetVerticalSpace(childLayout.Owner); if (!verticalSpace.Size.Equals(0)) { ellipsisTextHeight = true; needClearCache = true; } } if (!ellipsisTextWidth && RelativeLayout.GetFillHorizontal(childLayout.Owner)) { needMeasuredWidth = true; needClearCache = true; } if (!ellipsisTextHeight && RelativeLayout.GetFillVertical(childLayout.Owner)) { needMeasuredHeight = true; needClearCache = true; } if ((ellipsisTextWidth == false) && (ellipsisTextHeight == false) && (needMeasuredWidth == false) && (needMeasuredHeight == false)) { continue; } float width = childLayout.MeasuredWidth.Size.AsDecimal(); float height = childLayout.MeasuredHeight.Size.AsDecimal(); if (ellipsisTextWidth) { Geometry horizontalSpace = GetHorizontalSpace(childLayout.Owner); if (!horizontalSpace.Size.Equals(0)) { if ((width > horizontalSpace.Size) || ((width < horizontalSpace.Size) && RelativeLayout.GetFillVertical(childLayout.Owner))) { width = horizontalSpace.Size; } } } else if (needMeasuredWidth) { Geometry horizontalGeometry = GetHorizontalLayout(childLayout.Owner); width = horizontalGeometry.Size; } if (ellipsisTextHeight) { Geometry verticalSpace = GetVerticalSpace(childLayout.Owner); if (!verticalSpace.Size.Equals(0)) { if ((height > verticalSpace.Size) || ((height < verticalSpace.Size) && RelativeLayout.GetFillHorizontal(childLayout.Owner))) { height = verticalSpace.Size; } } } else if (needMeasuredHeight) { Geometry verticalGeometry = GetVerticalLayout(childLayout.Owner); height = verticalGeometry.Size; } // Padding sizes are added because Padding sizes will be subtracted in MeasureChild(). MeasureSpecification childWidthMeasureSpec = new MeasureSpecification(new LayoutLength(width + Padding.Start + Padding.End), MeasureSpecification.ModeType.Exactly); MeasureSpecification childHeightMeasureSpec = new MeasureSpecification(new LayoutLength(height + Padding.Top + Padding.Bottom), MeasureSpecification.ModeType.Exactly); // To calculate the grand children's Measure() with the mode type Exactly, // children's Measure() is called with MatchParent if the children have WrapContent. // // i.e. // If children have Wrapcontent and the grand children have MatchParent, // then grand children's MeasuredWidth/Height do not fill the children // because the grand children's Measure() is called with the mode type AtMost. int origWidthSpecification = childLayout.Owner.WidthSpecification; int origHeightSpecification = childLayout.Owner.HeightSpecification; if (ellipsisTextWidth || needMeasuredWidth) { origWidthSpecification = childLayout.Owner.WidthSpecification; childLayout.Owner.WidthSpecification = LayoutParamPolicies.MatchParent; } if (ellipsisTextHeight || needMeasuredHeight) { origHeightSpecification = childLayout.Owner.HeightSpecification; childLayout.Owner.HeightSpecification = LayoutParamPolicies.MatchParent; } MeasureChildWithMargins(childLayout, childWidthMeasureSpec, new LayoutLength(0), childHeightMeasureSpec, new LayoutLength(0)); if (ellipsisTextWidth || needMeasuredWidth) { childLayout.Owner.WidthSpecification = origWidthSpecification; } if (ellipsisTextHeight || needMeasuredHeight) { childLayout.Owner.HeightSpecification = origHeightSpecification; } } } if (needClearCache) { HorizontalRelativeCache.Clear(); VerticalRelativeCache.Clear(); } }
/// <summary> /// Constructor /// </summary> /// <param name="measuredSize">size parameter</param> /// <param name="state">State</param> public MeasuredSize(LayoutLength measuredSize, MeasuredSize.StateType state) { Size = measuredSize; State = state; }
public MeasuredSize ResolveSizeAndState(LayoutLength size, MeasureSpecification measureSpecification, MeasuredSize.StateType childMeasuredState) { return(base.ResolveSizeAndState(size, measureSpecification, childMeasuredState)); }
/// <inheritdoc/> /// <since_tizen> 9 </since_tizen> protected override void OnMeasure(MeasureSpecification widthMeasureSpec, MeasureSpecification heightMeasureSpec) { MeasuredSize.StateType childWidthState = MeasuredSize.StateType.MeasuredSizeOK; MeasuredSize.StateType childHeightState = MeasuredSize.StateType.MeasuredSizeOK; for (int i = 0; i < LayoutChildren.Count; i++) { LayoutItem childLayout = LayoutChildren[i]; if (childLayout != null) { MeasureChildWithMargins(childLayout, widthMeasureSpec, new LayoutLength(0), heightMeasureSpec, new LayoutLength(0)); if (childLayout.MeasuredWidth.State == MeasuredSize.StateType.MeasuredSizeTooSmall) { childWidthState = MeasuredSize.StateType.MeasuredSizeTooSmall; } if (childLayout.MeasuredHeight.State == MeasuredSize.StateType.MeasuredSizeTooSmall) { childHeightState = MeasuredSize.StateType.MeasuredSizeTooSmall; } } } (float childrenWidth, float childrenHeight) = CalculateChildrenSize(widthMeasureSpec.Size.AsDecimal(), heightMeasureSpec.Size.AsDecimal()); SetMeasuredDimensions(ResolveSizeAndState(new LayoutLength(childrenWidth), widthMeasureSpec, childWidthState), ResolveSizeAndState(new LayoutLength(childrenHeight), heightMeasureSpec, childHeightState)); // RelativeLayout sets its children's size in OnLayout(). // Therefore, the children's MeasuredWidth/Height are not the same with the children's size. // This causes that the grand children's MeasuredWidth/Height are calculated incorrectly. // To resolve the above, RelativeLayout updates its children's MeasuredWidth/Height after // the RelativeLayout's MeasuredWidth/Height are calculated. // // e.g. // Let parent have RelativeLayout and parent's size be 1920x1080. // Let child have WrapContent with SetFillHorizontal/Vertical true. // Let grand child have MatchParent. // Then, child's size is 1920x1080 but child's MeasuredWidth/Height is 0x0. // Then, grand child's MeasuredWidth/Height is 0x0 and size is 0x0. // // TODO: Not to do the following operation in OnLayout() again. for (int i = 0; i < LayoutChildren.Count; i++) { LayoutItem childLayout = LayoutChildren[i]; if (childLayout != null) { LayoutLength childLeft; LayoutLength childRight; LayoutLength childTop; LayoutLength childBottom; if (childLayout.Owner.WidthSpecification == LayoutParamPolicies.MatchParent) { childLeft = new LayoutLength(childLayout.Margin.Start); childRight = new LayoutLength(MeasuredWidth.Size.AsDecimal() - childLayout.Margin.End); } else { Geometry horizontalGeometry = GetHorizontalLayout(childLayout.Owner); childLeft = new LayoutLength(horizontalGeometry.Position + Padding.Start + childLayout.Margin.Start); childRight = new LayoutLength(horizontalGeometry.Position + horizontalGeometry.Size + Padding.Start - childLayout.Margin.End); } if (childLayout.Owner.HeightSpecification == LayoutParamPolicies.MatchParent) { childTop = new LayoutLength(childLayout.Margin.Top); childBottom = new LayoutLength(MeasuredHeight.Size.AsDecimal() - childLayout.Margin.Bottom); } else { Geometry verticalGeometry = GetVerticalLayout(childLayout.Owner); childTop = new LayoutLength(verticalGeometry.Position + Padding.Top + childLayout.Margin.Top); childBottom = new LayoutLength(verticalGeometry.Position + verticalGeometry.Size + Padding.Top - childLayout.Margin.Bottom); } // Padding sizes are added because Padding sizes will be subtracted in MeasureChild(). MeasureSpecification childWidthMeasureSpec = new MeasureSpecification(new LayoutLength(childRight.AsDecimal() - childLeft.AsDecimal() + Padding.Start + Padding.End), MeasureSpecification.ModeType.Exactly); MeasureSpecification childHeightMeasureSpec = new MeasureSpecification(new LayoutLength(childBottom.AsDecimal() - childTop.AsDecimal() + Padding.Top + Padding.Bottom), MeasureSpecification.ModeType.Exactly); int origWidthSpecification = childLayout.Owner.WidthSpecification; int origHeightSpecification = childLayout.Owner.HeightSpecification; // To calculate the grand children's Measure() with the mode type Exactly, // children's Measure() is called with MatchParent if the children have WrapContent. // // i.e. // If children have Wrapcontent and the grand children have MatchParent, // then grand children's MeasuredWidth/Height do not fill the children // because the grand children's Measure() is called with the mode type AtMost. if (childLayout.Owner.WidthSpecification == LayoutParamPolicies.WrapContent) { childLayout.Owner.WidthSpecification = LayoutParamPolicies.MatchParent; } if (childLayout.Owner.HeightSpecification == LayoutParamPolicies.WrapContent) { childLayout.Owner.HeightSpecification = LayoutParamPolicies.MatchParent; } // Use MeasureChild() because Margin sizes were already subtracted from childWidth/HeightMeasureSpec. MeasureChild(childLayout, childWidthMeasureSpec, childHeightMeasureSpec); childLayout.Owner.WidthSpecification = origWidthSpecification; childLayout.Owner.HeightSpecification = origHeightSpecification; } } }