예제 #1
0
        protected static MeasuredDimension ResolveSizeAndState(
            float size,
            MeasureSpec measureSpec,
            MeasuredStateFlags childMeasuredState)
        {
            MeasuredDimension result = new MeasuredDimension();

            MeasureMode specMode = measureSpec.Mode;
            float       specSize = measureSpec.Size;

            switch (specMode)
            {
            case MeasureSpec.Unspecified:
                result.Size = size;
                break;

            case MeasureSpec.AtMost:
                if (specSize < size)
                {
                    result.Size   = specSize;
                    result.State |= MeasuredStateFlags.TooSmall;
                }
                else
                {
                    result.Size = size;
                }
                break;

            case MeasureSpec.Exactly:
                result.Size = specSize;
                break;
            }

            result.State |= childMeasuredState;

            return(result);
        }
예제 #2
0
        protected override void OnMeasure(
            MeasureSpec widthMeasureSpec,
            MeasureSpec heightMeasureSpec)
        {
            var layoutProperties = this.LayoutProperties();

            Size availableSize = new Size(
                widthMeasureSpec.Size - layoutProperties.Padding.Left - layoutProperties.Padding.Right,
                heightMeasureSpec.Size - layoutProperties.Padding.Top - layoutProperties.Padding.Bottom);

            // Keep track of the space used by children
            float usedWidth  = 0;
            float usedHeight = 0;

            var remainingSize = availableSize;

            MeasuredStateFlags childWidthState  = MeasuredStateFlags.None;
            MeasuredStateFlags childHeightState = MeasuredStateFlags.None;
            int childCount = this.ChildCount;

            for (int i = 0; i < childCount; i += 1)
            {
                var child = this.GetChildAt(i);

                if (child.Hidden)
                {
                    continue;
                }

                var layoutParams = (LayoutParams)child.LayoutParameters();

                this.MeasureChildWithMarginsOverride(
                    child,
                    widthMeasureSpec,
                    usedWidth,
                    (layoutParams.Width == LayoutParams.MatchParent) ? LayoutParams.WrapContent : layoutParams.Width,
                    heightMeasureSpec,
                    usedHeight,
                    layoutParams.Height);

                var childSize = GetChildUsedSizeWithMargins(child, layoutParams);

                usedWidth += childSize.Width;
                usedHeight = Math.Max(usedHeight, childSize.Height);

                // Update the remaining size
                remainingSize = new Size(
                    (float)Math.Max(0, availableSize.Width - usedWidth),
                    (float)Math.Max(0, availableSize.Height));

                // Update the child state
                childWidthState  = CombineMeasuredStates(childWidthState, child.LayoutProperties().MeasuredSize.WidthState);
                childHeightState = CombineMeasuredStates(childHeightState, child.LayoutProperties().MeasuredSize.HeightState);
            }

            // Calculate the total size used by children
            Size usedSize = new Size(
                (float)Math.Max(0, usedWidth),
                (float)Math.Max(0, usedHeight));

            // Default the final size to the size used by children
            var finalSize = usedSize;

            var dimensionX = ResolveSizeAndState(finalSize.Width, widthMeasureSpec, childWidthState);
            var dimensionY = ResolveSizeAndState(finalSize.Height, heightMeasureSpec, childHeightState);

            this.SetMeasuredSize(dimensionX, dimensionY);
        }
예제 #3
0
 protected static MeasuredStateFlags CombineMeasuredStates(
     MeasuredStateFlags currentState,
     MeasuredStateFlags newState)
 {
     return(currentState | newState);
 }