[NUI] Fix LinearLayout to update its child's MeasuredSizeHeight 0 correctly
[platform/core/csapi/tizenfx.git] / src / Tizen.NUI / src / public / Layouting / LinearLayout.cs
index cd2e50d..3450182 100755 (executable)
@@ -15,6 +15,7 @@
  */
 
 using System;
+using System.ComponentModel;
 using Tizen.NUI.BaseComponents;
 using System.Collections.Generic;
 using System.Linq;
@@ -26,6 +27,8 @@ namespace Tizen.NUI
     /// </summary>
     public class LinearLayout : LayoutGroup
     {
+        private Alignment linearAlignment = Alignment.Top;
+
         /// <summary>
         /// [Draft] Enumeration for the direction in which the content is laid out
         /// </summary>
@@ -46,6 +49,7 @@ namespace Tizen.NUI
         /// [Draft] Enumeration for the alignment of the linear layout items
         /// </summary>
         /// <since_tizen> 6 </since_tizen>
+        [Obsolete("This has been deprecated in API9 and will be removed in API11. Use HorizontalAlignment and VerticalAlignment instead.")]
         public enum Alignment
         {
             /// <summary>
@@ -115,6 +119,11 @@ namespace Tizen.NUI
         {
             get
             {
+                if (cellPadding == null)
+                {
+                    cellPadding = new Size2D(0, 0);
+                }
+
                 return cellPadding;
             }
             set
@@ -129,7 +138,64 @@ namespace Tizen.NUI
         /// [Draft] Get/Set the alignment in the layout
         /// </summary>
         /// <since_tizen> 6 </since_tizen>
-        public LinearLayout.Alignment LinearAlignment { get; set; } = Alignment.Top;
+        [Obsolete("This has been deprecated in API9 and will be removed in API11. Use HorizontalAlignment and VerticalAlignment properties instead.")]
+        public LinearLayout.Alignment LinearAlignment
+        {
+            get
+            {
+                return linearAlignment;
+            }
+
+            set
+            {
+                if (linearAlignment == value)
+                {
+                    return;
+                }
+
+                linearAlignment = value;
+
+                switch (linearAlignment)
+                {
+                    case Alignment.Begin:
+                        HorizontalAlignment = HorizontalAlignment.Begin;
+                        break;
+                    case Alignment.End:
+                        HorizontalAlignment = HorizontalAlignment.End;
+                        break;
+                    case Alignment.CenterHorizontal:
+                        HorizontalAlignment = HorizontalAlignment.Center;
+                        break;
+                    case Alignment.Top:
+                        VerticalAlignment = VerticalAlignment.Top;
+                        break;
+                    case Alignment.Bottom:
+                        VerticalAlignment = VerticalAlignment.Bottom;
+                        break;
+                    case Alignment.CenterVertical:
+                        VerticalAlignment = VerticalAlignment.Center;
+                        break;
+                    case Alignment.Center:
+                        HorizontalAlignment = HorizontalAlignment.Center;
+                        VerticalAlignment = VerticalAlignment.Center;
+                        break;
+                    default:
+                        break;
+                }
+            }
+         }
+
+        /// <summary>
+        /// Get/Set the horizontal alignment in the layout
+        /// </summary>
+        /// <since_tizen> 9 </since_tizen>
+        public HorizontalAlignment HorizontalAlignment { get; set; } = HorizontalAlignment.Begin;
+
+        /// <summary>
+        /// Get/Set the vertical alignment in the layout
+        /// </summary>
+        /// <since_tizen> 9 </since_tizen>
+        public VerticalAlignment VerticalAlignment { get; set; } = VerticalAlignment.Top;
 
         private float totalLength = 0.0f;
         private Size2D cellPadding = new Size2D(0, 0);
@@ -202,11 +268,11 @@ namespace Tizen.NUI
 
             if (horizontal)
             {
-                childWidthMeasureSpec = new MeasureSpecification(new LayoutLength(childsShare), MeasureSpecification.ModeType.Exactly);
+                childWidthMeasureSpec = new MeasureSpecification(new LayoutLength(childsShare - (childLayout.Margin.Start + childLayout.Margin.End)), MeasureSpecification.ModeType.Exactly);
 
                 childHeightMeasureSpec = GetChildMeasureSpecification(
                                             new MeasureSpecification(
-                                                new LayoutLength(heightMeasureSpec.Size - (childLayout.Owner.Margin.Top + childLayout.Owner.Margin.Bottom)),
+                                                new LayoutLength(heightMeasureSpec.Size - (childLayout.Margin.Top + childLayout.Margin.Bottom)),
                                                 heightMeasureSpec.Mode),
                                             new LayoutLength(Padding.Top + Padding.Bottom),
                                             new LayoutLength(desiredHeight));
@@ -215,12 +281,12 @@ namespace Tizen.NUI
             {
                 childWidthMeasureSpec = GetChildMeasureSpecification(
                                             new MeasureSpecification(
-                                                new LayoutLength(widthMeasureSpec.Size - (childLayout.Owner.Margin.Start + childLayout.Owner.Margin.End)),
+                                                new LayoutLength(widthMeasureSpec.Size - (childLayout.Margin.Start + childLayout.Margin.End)),
                                                 widthMeasureSpec.Mode),
                                             new LayoutLength(Padding.Start + Padding.End),
                                             new LayoutLength(desiredWidth));
 
-                childHeightMeasureSpec = new MeasureSpecification(new LayoutLength(childsShare), MeasureSpecification.ModeType.Exactly);
+                childHeightMeasureSpec = new MeasureSpecification(new LayoutLength(childsShare - (childLayout.Margin.Top + childLayout.Margin.Bottom)), MeasureSpecification.ModeType.Exactly);
             }
 
             childLayout.Measure(childWidthMeasureSpec, childHeightMeasureSpec);
@@ -242,7 +308,7 @@ namespace Tizen.NUI
         {
             var widthMode = widthMeasureSpec.Mode;
             var heightMode = heightMeasureSpec.Mode;
-            bool isExactly = (widthMode == MeasureSpecification.ModeType.Exactly);
+            bool isWidthExactly = (widthMode == MeasureSpecification.ModeType.Exactly);
             bool isHeightExactly = (heightMode == MeasureSpecification.ModeType.Exactly);
             float maxHeight = 0.0f;
             float totalWeight = 0.0f;
@@ -265,33 +331,36 @@ namespace Tizen.NUI
             // We measure all children whose width specification policy is WrapContent without weight.
             // After 1st phase, remaining width of parent is accumulated to calculate width of children
             // whose width specification policy is MatchParent.
-            foreach (LayoutItem childLayout in IterateLayoutChildren())
+            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 useRemainingWidth = (childDesiredWidth == 0) && (childWeight > 0);
 
-                totalWeight += childWeight;
-
                 if ((childDesiredWidth == LayoutParamPolicies.MatchParent) || (useRemainingWidth))
                 {
+                    totalWeight += childWeight;
                     childrenMatchParentCount++;
                 }
 
-                if (isHeightExactly && useRemainingWidth)
-                {
-                    totalLength = Math.Max(totalLength, totalLength + childMarginWidth);
-                }
-                else
+                // 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 ((childDesiredWidth == LayoutParamPolicies.WrapContent) || ((childDesiredWidth >= 0) && (!useRemainingWidth)))
                 {
-                    if ((childDesiredWidth >= 0) || (childDesiredWidth == LayoutParamPolicies.WrapContent))
-                    {
-                        MeasureChildWithMargins(childLayout, widthMeasureSpec, new LayoutLength(0), heightMeasureSpec, new LayoutLength(0));
-                    }
+                    MeasureChildWithMargins(childLayout, widthMeasureSpec, new LayoutLength(0), heightMeasureSpec, new LayoutLength(0));
 
                     float childMeasuredWidth = childLayout.MeasuredWidth.Size.AsDecimal();
 
@@ -313,51 +382,93 @@ namespace Tizen.NUI
                 {
                     childState.heightState = MeasuredSize.StateType.MeasuredSizeTooSmall;
                 }
-
-                float childMeasuredHeight = childLayout.MeasuredHeight.Size.AsDecimal();
-                if (childMeasuredHeight < 0)
-                {
-                    maxHeight = Math.Max(maxHeight, childMarginHeight);
-                }
-                else
-                {
-                    maxHeight = Math.Max(maxHeight, childMeasuredHeight + childMarginHeight);
-                }
             } // 1ST PHASE foreach
 
-            totalLength = Math.Max(totalLength, totalLength + CellPadding.Width * (childrenCount - 1));
+            totalLength = Math.Max(totalLength, totalLength + CellPadding.Width * (childrenCount - 1) + Padding.Start + Padding.End);
             float widthSize = Math.Max(totalLength, SuggestedMinimumWidth.AsDecimal());
-            MeasuredSize widthSizeAndState = ResolveSizeAndState(new LayoutLength(widthSize + Padding.Start + Padding.End), widthMeasureSpec, MeasuredSize.StateType.MeasuredSizeOK);
+            MeasuredSize widthSizeAndState = ResolveSizeAndState(new LayoutLength(widthSize), widthMeasureSpec, MeasuredSize.StateType.MeasuredSizeOK);
             widthSize = widthSizeAndState.Size.AsDecimal();
 
-            float remainingWidth = widthSize - totalLength - (Padding.Start + Padding.End);
+            float remainingWidth = widthSize - 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 = widthSize;
+            }
+
             // 2ND PHASE:
             //
             // We measure all children whose width specification policy is MatchParent without weight.
             // After 2nd phase, all children's widths are calculated without considering weight.
             // And the widths of all weighted children are accumulated to calculate weighted width.
-            foreach (LayoutItem childLayout in IterateLayoutChildren())
+            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;
                 bool useRemainingWidth = (childDesiredWidth == 0) && (childWeight > 0);
                 bool needToMeasure = false;
 
-                if (isExactly && ((childDesiredHeight == LayoutParamPolicies.MatchParent) || (useRemainingWidth)))
+                if ((childDesiredHeight == LayoutParamPolicies.MatchParent) || (useRemainingWidth))
                 {
-                    childLayout.Owner.HeightSpecification = (int)heightMeasureSpec.Size.AsDecimal() - (childLayout.Margin.Top + childLayout.Margin.Bottom) - (Padding.Top + Padding.Bottom);
-                    needToMeasure = true;
+                    if (isHeightExactly)
+                    {
+                        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 (remainingWidth > 0)
                 {
                     if ((childDesiredWidth == LayoutParamPolicies.MatchParent) || (useRemainingWidth))
                     {
-                        childLayout.Owner.WidthSpecification = (int)(remainingWidth / childrenMatchParentCount);
-                        needToMeasure = true;
+                        if (isWidthExactly)
+                        {
+                            // In MeasureChildWithMargins(), it is assumed that widthMeasureSpec includes Padding.Start and Padding.End.
+                            // Therefore, Padding.Start and Padding.End are added to widthMeasureSpec.Size before it is passed to MeasureChildWithMargins().
+                            widthMeasureSpec.SetSize(new LayoutLength((int)(remainingWidth / childrenMatchParentCount) + Padding.Start + Padding.End));
+                            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!");
+                            }
+                        }
                     }
                 }
 
@@ -366,13 +477,17 @@ namespace Tizen.NUI
                     MeasureChildWithMargins(childLayout, widthMeasureSpec, new LayoutLength(0), heightMeasureSpec, new LayoutLength(0));
                 }
 
-                if (childWeight > 0)
+                if ((childWeight > 0) && ((childDesiredWidth == LayoutParamPolicies.MatchParent) || (childDesiredWidth == 0)))
                 {
                     float childMeasuredWidth = childLayout.MeasuredWidth.Size.AsDecimal();
 
-                    if (childMeasuredWidth > 0)
+                    if (childMeasuredWidth < 0)
                     {
-                        totalWeightLength += childMeasuredWidth;
+                        totalWeightLength = Math.Max(totalWeightLength, totalWeightLength + childMargin.Start + childMargin.End);
+                    }
+                    else
+                    {
+                        totalWeightLength = Math.Max(totalWeightLength, totalWeightLength + childMeasuredWidth + childMargin.Start + childMargin.End);
                     }
                 }
             } // 2ND PHASE foreach
@@ -384,21 +499,67 @@ namespace Tizen.NUI
             // in remaining width of parent.
             if (totalWeight > 0.0f)
             {
-                foreach (LayoutItem childLayout in IterateLayoutChildren())
+                foreach (LayoutItem childLayout in LayoutChildren)
                 {
-                    float desiredChildHeight = childLayout.Owner.HeightSpecification;
+                    if (!childLayout.SetPositionByLayout)
+                    {
+                        continue;
+                    }
+                    int childDesiredWidth = childLayout.Owner.WidthSpecification;
                     float childWeight = childLayout.Owner.Weight;
-                    Extents childMargin = childLayout.Margin;
 
-                    if (childWeight > 0)
+                    if ((childWeight > 0) && ((childDesiredWidth == LayoutParamPolicies.MatchParent) || (childDesiredWidth == 0)))
                     {
-                        MeasureWeightedChild(childLayout, totalWeightLength, totalWeight, childWeight,
-                                             widthMeasureSpec, heightMeasureSpec, childState,
-                                             Orientation.Horizontal);
+                        if (isWidthExactly)
+                        {
+                            MeasureWeightedChild(childLayout, totalWeightLength, totalWeight, childWeight,
+                                                 widthMeasureSpec, heightMeasureSpec, childState,
+                                                 Orientation.Horizontal);
+                        }
+                        // 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!");
+                            }
+                        }
                     }
-                } // 3RD PHASE foreach
+                }
             }
+            // 3RD PHASE foreach
 
+            // Decide the max height among children.
+            foreach (var childLayout in LayoutChildren)
+            {
+                if (!childLayout.SetPositionByLayout)
+                {
+                    continue;
+                }
+
+                Extents childMargin = childLayout.Margin;
+                float childMarginHeight = childMargin.Top + childMargin.Bottom;
+                float childMeasuredHeight = childLayout.MeasuredHeight.Size.AsDecimal();
+
+                if (childMeasuredHeight < 0)
+                {
+                    maxHeight = Math.Max(maxHeight, childMarginHeight);
+                }
+                else
+                {
+                    maxHeight = Math.Max(maxHeight, childMeasuredHeight + childMarginHeight);
+                }
+            }
+
+            // Decide the max height compared with paddings and its suggested height.
             maxHeight = Math.Max(maxHeight, maxHeight + (Padding.Top + Padding.Bottom));
             maxHeight = Math.Max(maxHeight, SuggestedMinimumHeight.AsRoundedValue());
 
@@ -435,33 +596,36 @@ namespace Tizen.NUI
             // 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 (LayoutItem childLayout in IterateLayoutChildren())
+            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);
 
-                totalWeight += childWeight;
-
                 if ((childDesiredHeight == LayoutParamPolicies.MatchParent) || (useRemainingHeight))
                 {
+                    totalWeight += childWeight;
                     childrenMatchParentCount++;
                 }
 
-                if (isHeightExactly && useRemainingHeight)
-                {
-                    totalLength = Math.Max(totalLength, totalLength + childMarginHeight);
-                }
-                else
+                // 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)))
                 {
-                    if ((childDesiredHeight > 0) || (childDesiredHeight == LayoutParamPolicies.WrapContent))
-                    {
-                        MeasureChildWithMargins(childLayout, widthMeasureSpec, new LayoutLength(0), heightMeasureSpec, new LayoutLength(0));
-                    }
+                    MeasureChildWithMargins(childLayout, widthMeasureSpec, new LayoutLength(0), heightMeasureSpec, new LayoutLength(0));
 
                     float childMeasuredHeight = childLayout.MeasuredHeight.Size.AsDecimal();
 
@@ -483,51 +647,93 @@ namespace Tizen.NUI
                 {
                     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));
+            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 + Padding.Top + Padding.Bottom), heightMeasureSpec, MeasuredSize.StateType.MeasuredSizeOK);
+            MeasuredSize heightSizeAndState = ResolveSizeAndState(new LayoutLength(heightSize), heightMeasureSpec, MeasuredSize.StateType.MeasuredSizeOK);
             heightSize = heightSizeAndState.Size.AsDecimal();
 
-            float remainingHeight = heightSize - totalLength - (Padding.Top + Padding.Bottom);
+            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 (LayoutItem childLayout in IterateLayoutChildren())
+            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;
                 bool useRemainingHeight = (childDesiredHeight == 0) && (childWeight > 0);
                 bool needToMeasure = false;
 
-                if ((isWidthExactly) && ((childDesiredWidth == LayoutParamPolicies.MatchParent) || (useRemainingHeight)))
+                if ((childDesiredWidth == LayoutParamPolicies.MatchParent) || (useRemainingHeight))
                 {
-                    childLayout.Owner.WidthSpecification = (int)widthMeasureSpec.Size.AsDecimal() - (childLayout.Margin.Start + childLayout.Margin.End) - (Padding.Start + Padding.End);
-                    needToMeasure = true;
+                    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))
                     {
-                        childLayout.Owner.HeightSpecification = (int)(remainingHeight / childrenMatchParentCount);
-                        needToMeasure = true;
+                        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!");
+                            }
+                        }
                     }
                 }
 
@@ -536,13 +742,17 @@ namespace Tizen.NUI
                     MeasureChildWithMargins(childLayout, widthMeasureSpec, new LayoutLength(0), heightMeasureSpec, new LayoutLength(0));
                 }
 
-                if (childWeight > 0)
+                if ((childWeight > 0) && ((childDesiredHeight == LayoutParamPolicies.MatchParent) || (childDesiredHeight == 0)))
                 {
                     float childMeasuredHeight = childLayout.MeasuredHeight.Size.AsDecimal();
 
-                    if (childMeasuredHeight > 0)
+                    if (childMeasuredHeight < 0)
                     {
-                        totalWeightLength += childMeasuredHeight;
+                        totalWeightLength = Math.Max(totalWeightLength, totalWeightLength + childMargin.Top + childMargin.Bottom);
+                    }
+                    else
+                    {
+                        totalWeightLength = Math.Max(totalWeightLength, totalWeightLength + childMeasuredHeight + childMargin.Top + childMargin.Bottom);
                     }
                 }
             } // 2ND PHASE foreach
@@ -554,21 +764,66 @@ namespace Tizen.NUI
             // in remaining height of parent.
             if (totalWeight > 0)
             {
-                foreach (LayoutItem childLayout in IterateLayoutChildren())
+                foreach (var childLayout in LayoutChildren)
                 {
-                    float desiredChildWidth = childLayout.Owner.WidthSpecification;
+                    if (!childLayout.SetPositionByLayout)
+                    {
+                        continue;
+                    }
+                    int childDesiredHeight = childLayout.Owner.HeightSpecification;
                     float childWeight = childLayout.Owner.Weight;
-                    Extents childMargin = childLayout.Margin;
 
-                    if (childWeight > 0)
+                    if ((childWeight > 0) && ((childDesiredHeight == LayoutParamPolicies.MatchParent) || (childDesiredHeight == 0)))
                     {
-                        MeasureWeightedChild(childLayout, totalWeightLength, totalWeight, childWeight,
-                                             widthMeasureSpec, heightMeasureSpec, childState,
-                                             Orientation.Vertical);
+                        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
+                }
+            } // 3RD PHASE foreach
+
+            // Decide the max width among children.
+            foreach (var childLayout in LayoutChildren)
+            {
+                if (!childLayout.SetPositionByLayout)
+                {
+                    continue;
+                }
+
+                Extents childMargin = childLayout.Margin;
+                float childMarginWidth = childMargin.Start + childMargin.End;
+                float childMeasuredWidth = childLayout.MeasuredWidth.Size.AsDecimal();
+
+                if (childMeasuredWidth < 0)
+                {
+                    maxWidth = Math.Max(maxWidth, childMarginWidth);
+                }
+                else
+                {
+                    maxWidth = Math.Max(maxWidth, childMeasuredWidth + childMarginWidth);
+                }
             }
 
+            // Decide the max width compared with paddings and its suggested width.
             maxWidth = Math.Max(maxWidth, maxWidth + (Padding.Start + Padding.End));
             maxWidth = Math.Max(maxWidth, SuggestedMinimumWidth.AsRoundedValue());
 
@@ -591,12 +846,12 @@ namespace Tizen.NUI
             // Space available for child
             LayoutLength childSpace = new LayoutLength(height - Padding.Top - Padding.Bottom);
 
-            List<LayoutItem> LinearChildren = IterateLayoutChildren().ToList();
-            int count = LinearChildren.Count;
+            var LinearChildren = IterateLayoutChildren();
+            int count = LinearChildren.Count<LayoutItem>();
 
-            switch (LinearAlignment)
+            switch (HorizontalAlignment)
             {
-                case Alignment.End:
+                case HorizontalAlignment.End:
                     // totalLength contains the padding already
                     // In case of RTL map END alignment to the left edge
                     if (isLayoutRtl)
@@ -608,12 +863,11 @@ namespace Tizen.NUI
                         childLeft = new LayoutLength(Padding.Start + right.AsDecimal() - left.AsDecimal() - totalLength);
                     }
                     break;
-                case Alignment.CenterHorizontal: // FALL THROUGH
-                case Alignment.Center:
+                case HorizontalAlignment.Center:
                     // totalLength contains the padding already
                     childLeft = new LayoutLength(Padding.Start + (right.AsDecimal() - left.AsDecimal() - totalLength) / 2.0f);
                     break;
-                case Alignment.Begin: // FALL THROUGH (default)
+                case HorizontalAlignment.Begin: // FALL THROUGH (default)
                 default:
                     // totalLength contains the padding already
                     // In case of RTL map BEGIN alignment to the right edge
@@ -642,22 +896,21 @@ namespace Tizen.NUI
             {
                 int childIndex = start + dir * i;
                 // Get a reference to the childLayout at the given index
-                LayoutItem childLayout = LinearChildren[childIndex];
+                LayoutItem childLayout = LinearChildren.ElementAt<LayoutItem>(i);
 
                 LayoutLength childWidth = childLayout.MeasuredWidth.Size;
                 LayoutLength childHeight = childLayout.MeasuredHeight.Size;
                 Extents childMargin = childLayout.Margin;
 
-                switch (LinearAlignment)
+                switch (VerticalAlignment)
                 {
-                    case Alignment.Bottom:
+                    case VerticalAlignment.Bottom:
                         childTop = new LayoutLength(height - Padding.Bottom - childHeight - childMargin.Bottom);
                         break;
-                    case Alignment.CenterVertical:
-                    case Alignment.Center: // FALLTHROUGH
+                    case VerticalAlignment.Center:
                         childTop = new LayoutLength(Padding.Top + ((childSpace - childHeight).AsDecimal() / 2.0f) + childMargin.Top - childMargin.Bottom);
                         break;
-                    case Alignment.Top: // FALLTHROUGH default
+                    case VerticalAlignment.Top: // FALLTHROUGH default
                     default:
                         childTop = new LayoutLength(Padding.Top + childMargin.Top);
                         break;
@@ -679,21 +932,20 @@ namespace Tizen.NUI
             // Space available for child
             LayoutLength childSpace = new LayoutLength(width - Padding.Start - Padding.End);
 
-            List<LayoutItem> LinearChildren = IterateLayoutChildren().ToList();
-            int count = LinearChildren.Count;
+            var LinearChildren = IterateLayoutChildren();
+            int count = LinearChildren.Count<LayoutItem>();
 
-            switch (LinearAlignment)
+            switch (VerticalAlignment)
             {
-                case Alignment.Bottom:
+                case VerticalAlignment.Bottom:
                     // totalLength contains the padding already
                     childTop = new LayoutLength(Padding.Top + bottom.AsDecimal() - top.AsDecimal() - totalLength);
                     break;
-                case Alignment.CenterVertical: // FALL THROUGH
-                case Alignment.Center:
+                case VerticalAlignment.Center:
                     // totalLength contains the padding already
                     childTop = new LayoutLength(Padding.Top + (bottom.AsDecimal() - top.AsDecimal() - totalLength) / 2.0f);
                     break;
-                case Alignment.Top:  // FALL THROUGH (default)
+                case VerticalAlignment.Top:  // FALL THROUGH (default)
                 default:
                     // totalLength contains the padding already
                     childTop = new LayoutLength(Padding.Top);
@@ -702,28 +954,27 @@ namespace Tizen.NUI
 
             for (int i = 0; i < count; i++)
             {
-                LayoutItem childLayout = LinearChildren[i];
+                LayoutItem childLayout = LinearChildren.ElementAt<LayoutItem>(i);
 
                 LayoutLength childWidth = childLayout.MeasuredWidth.Size;
                 LayoutLength childHeight = childLayout.MeasuredHeight.Size;
                 Extents childMargin = childLayout.Margin;
 
                 childTop += childMargin.Top;
-                switch (LinearAlignment)
+                switch (HorizontalAlignment)
                 {
-                    case Alignment.Begin:
+                    case HorizontalAlignment.Begin:
                     default:
                         {
                             childLeft = new LayoutLength(Padding.Start + childMargin.Start);
                             break;
                         }
-                    case Alignment.End:
+                    case HorizontalAlignment.End:
                         {
                             childLeft = new LayoutLength(width - Padding.End - childWidth - childMargin.End);
                             break;
                         }
-                    case Alignment.CenterHorizontal:
-                    case Alignment.Center: // FALL THROUGH
+                    case HorizontalAlignment.Center:
                         {
                             childLeft = new LayoutLength(Padding.Start + ((childSpace - childWidth).AsDecimal() / 2.0f) + childMargin.Start - childMargin.End);
                             break;
@@ -740,8 +991,12 @@ namespace Tizen.NUI
             // ourselves. The measured height should be the max height of the children, changed
             // to accommodate the heightMeasureSpec from the parent
             MeasureSpecification uniformMeasureSpec = new MeasureSpecification(MeasuredHeight.Size, MeasureSpecification.ModeType.Exactly);
-            foreach (LayoutItem childLayout in IterateLayoutChildren())
+            foreach (var childLayout in LayoutChildren)
             {
+                if (!childLayout.SetPositionByLayout)
+                {
+                    continue;
+                }
                 int desiredChildHeight = childLayout.Owner.HeightSpecification;
                 int desiredChildWidth = childLayout.Owner.WidthSpecification;