public long ComputeInfoCode(long offset) { int count = ChildCount; long result = offset; int index = 0; for (int i = 0; i < count; i++) { View child = GetChildAt(i); result = ComputeHash(result, (int)child.Visibility, index++); ViewLayoutParams lp = (ViewLayoutParams)child.LayoutParameters; result = ComputeHash(result, lp.Layer, index++); result = ComputeHash(result, (int)lp.Gravity, index++); result = ComputeHash(result, lp.Width, index++); result = ComputeHash(result, lp.Height, index++); result = ComputeHash(result, lp.LeftMargin, index++); result = ComputeHash(result, lp.TopMargin, index++); result = ComputeHash(result, lp.RightMargin, index++); result = ComputeHash(result, lp.BottomMargin, index++); } return(result); }
public ViewLayoutParams(ViewLayoutParams source) : base(source) { this.Gravity = source.Gravity; this.Layer = source.Layer; }
protected override void OnMeasure(int widthMeasureSpec, int heightMeasureSpec) { long code = ComputeInfoCode((long)widthMeasureSpec + heightMeasureSpec); if (code == viewInfoCode) { SetMeasuredDimension(MeasuredWidth, MeasuredHeight); return; } viewInfoCode = code; int paddingWidth = PaddingLeft + PaddingRight; int paddingHeight = PaddingTop + PaddingBottom; int smsw = MeasureUtils.MakeSelfMeasureSpec(widthMeasureSpec, paddingWidth); int smsh = MeasureUtils.MakeSelfMeasureSpec(heightMeasureSpec, paddingHeight); int smswnp = MeasureUtils.MakeSelfMeasureSpec(widthMeasureSpec, 0); int smshnp = MeasureUtils.MakeSelfMeasureSpec(heightMeasureSpec, 0); int contentWidth = 0; int contentHeight = 0; for (int i = 0; i < ChildCount; i++) { View child = GetChildAt(i); if (child.Visibility == ViewStates.Gone) { continue; } ViewLayoutParams lp = (ViewLayoutParams)child.LayoutParameters; int marginWidth = lp.LeftMargin + lp.RightMargin; int marginHeight = lp.TopMargin + lp.BottomMargin; int cmsw, cmsh; switch (lp.Layer) { case ViewLayoutParams.LAYER_LEFT: case ViewLayoutParams.LAYER_RIGHT: case ViewLayoutParams.LAYER_TOP: case ViewLayoutParams.LAYER_BOTTOM: cmsw = MeasureUtils.MakeChildMeasureSpec(smswnp, lp.Width, marginWidth); cmsh = MeasureUtils.MakeChildMeasureSpec(smshnp, lp.Height, marginHeight); break; default: cmsw = MeasureUtils.MakeChildMeasureSpec(smsw, lp.Width, marginWidth); cmsh = MeasureUtils.MakeChildMeasureSpec(smsh, lp.Height, marginHeight); break; } child.Measure(cmsw, cmsh); int cw = marginWidth + child.MeasuredWidth; int ch = marginHeight + child.MeasuredHeight; if (cw > contentWidth) { contentWidth = cw; } if (ch > contentHeight) { contentHeight = ch; } } contentWidth += paddingWidth; contentHeight += paddingHeight; int width = MeasureUtils.GetMeasuredDimension(contentWidth, widthMeasureSpec); int height = MeasureUtils.GetMeasuredDimension(contentHeight, heightMeasureSpec); SetMeasuredDimension(width, height); EdgeSize.SetEmpty(); CenterRect.Left = PaddingLeft; CenterRect.Top = PaddingTop; int centerWidth = Math.Max(MeasuredWidth - PaddingLeft - PaddingRight, 0); int centerHeight = Math.Max(MeasuredHeight - PaddingTop - PaddingBottom, 0); CenterRect.Right = CenterRect.Left + centerWidth; CenterRect.Bottom = CenterRect.Top + centerHeight; for (int i = 0; i < ChildCount; i++) { View child = GetChildAt(i); if (child.Visibility == ViewStates.Gone) { continue; } ViewLayoutParams lp = (ViewLayoutParams)child.LayoutParameters; int widthSpace = child.MeasuredWidth + lp.LeftMargin + lp.RightMargin; int heightSpace = child.MeasuredHeight + lp.TopMargin + lp.BottomMargin; switch (lp.Layer) { case ViewLayoutParams.LAYER_LEFT: if (widthSpace > EdgeSize.Left) { EdgeSize.Left = widthSpace; } break; case ViewLayoutParams.LAYER_TOP: if (heightSpace > EdgeSize.Top) { EdgeSize.Top = heightSpace; } break; case ViewLayoutParams.LAYER_RIGHT: if (widthSpace > EdgeSize.Right) { EdgeSize.Right = widthSpace; } break; case ViewLayoutParams.LAYER_BOTTOM: if (heightSpace > EdgeSize.Bottom) { EdgeSize.Bottom = heightSpace; } break; case ViewLayoutParams.LAYER_NONE: case ViewLayoutParams.LAYER_CENTER: default: break; } } }