private void ApplyGravityToLine(LineDefinition line) { int viewCount = line.Views.Count; if (viewCount <= 0) { return; } float totalWeight = 0; foreach (View prev in line.Views) { CustomLayoutParams plp = (CustomLayoutParams)prev.LayoutParameters; totalWeight += this.GetWeight(plp); } View lastChild = line.Views[viewCount - 1]; CustomLayoutParams lastChildLayoutParams = (CustomLayoutParams)lastChild.LayoutParameters; int excessLength = line.LineLength - (lastChildLayoutParams.Length + lastChildLayoutParams.InlineStartLength); int excessOffset = 0; foreach (View child in line.Views) { CustomLayoutParams layoutParams = (CustomLayoutParams)child.LayoutParameters; float weight = this.GetWeight(layoutParams); GravityFlags gravity = this.GetGravity(layoutParams); int extraLength = (int)Math.Round((double)(excessLength * weight / totalWeight)); int childLength = layoutParams.Length + layoutParams.SpacingLength; int childThickness = layoutParams.Thickness + layoutParams.SpacingThickness; Rect container = new Rect(); container.Top = 0; container.Left = excessOffset; container.Right = childLength + extraLength + excessOffset; container.Bottom = line.LineThickness; Rect result = new Rect(); Android.Views.Gravity.Apply(gravity, childLength, childThickness, container, result); excessOffset += extraLength; layoutParams.InlineStartLength = result.Left + layoutParams.InlineStartLength; layoutParams.InlineStartThickness = result.Top; layoutParams.Length = result.Width() - layoutParams.SpacingLength; layoutParams.Thickness = result.Height() - layoutParams.SpacingThickness; } }
private void ApplyPositionsToViews(LineDefinition line) { foreach (View child in line.Views) { CustomLayoutParams layoutParams = (CustomLayoutParams)child.LayoutParameters; if (this.config.Orientation == HORIZONTAL) { layoutParams.SetPosition(this.PaddingLeft + line.LineStartLength + layoutParams.InlineStartLength, this.PaddingTop + line.LineStartThickness + layoutParams.InlineStartThickness); child.Measure(MeasureSpec.MakeMeasureSpec(layoutParams.Length, MeasureSpecMode.Exactly), MeasureSpec.MakeMeasureSpec(layoutParams.Thickness, MeasureSpecMode.Exactly)); } else { layoutParams.SetPosition(this.PaddingLeft + line.LineStartThickness + layoutParams.InlineStartThickness, this.PaddingTop + line.LineStartLength + layoutParams.InlineStartLength); child.Measure(MeasureSpec.MakeMeasureSpec(layoutParams.Thickness, MeasureSpecMode.Exactly), MeasureSpec.MakeMeasureSpec(layoutParams.Length, MeasureSpecMode.Exactly)); } } }
private void ApplyGravityToLines(IList <LineDefinition> lines, int realControlLength, int realControlThickness) { int linesCount = lines.Count; if (linesCount <= 0) { return; } int totalWeight = linesCount; LineDefinition lastLine = lines[linesCount - 1]; int excessThickness = realControlThickness - (lastLine.LineThickness + lastLine.LineStartThickness); int excessOffset = 0; foreach (LineDefinition child in lines) { int weight = 1; GravityFlags gravity = this.Gravity; int extraThickness = (int)Math.Round((double)(excessThickness * weight / totalWeight)); int childLength = child.LineLength; int childThickness = child.LineThickness; Rect container = new Rect(); container.Top = excessOffset; container.Left = 0; container.Right = realControlLength; container.Bottom = childThickness + extraThickness + excessOffset; Rect result = new Rect(); Android.Views.Gravity.Apply(gravity, childLength, childThickness, container, result); excessOffset += extraThickness; child.AddLineStartLength(result.Left); child.AddLineStartThickness(result.Top); child.Length = result.Width(); child.Thickness = result.Height(); } }
protected override void OnMeasure(int widthMeasureSpec, int heightMeasureSpec) { int sizeWidth = MeasureSpec.GetSize(widthMeasureSpec) - this.PaddingRight - this.PaddingLeft; int sizeHeight = MeasureSpec.GetSize(heightMeasureSpec) - this.PaddingTop - this.PaddingBottom; MeasureSpecMode modeWidth = MeasureSpec.GetMode(widthMeasureSpec); MeasureSpecMode modeHeight = MeasureSpec.GetMode(heightMeasureSpec); int controlMaxLength = this.config.Orientation == HORIZONTAL ? sizeWidth : sizeHeight; int controlMaxThickness = this.config.Orientation == HORIZONTAL ? sizeHeight : sizeWidth; MeasureSpecMode modeLength = this.config.Orientation == HORIZONTAL ? modeWidth : modeHeight; MeasureSpecMode modeThickness = this.config.Orientation == HORIZONTAL ? modeHeight : modeWidth; lines.Clear(); LineDefinition currentLine = new LineDefinition(controlMaxLength, config); lines.Add(currentLine); int count = this.ChildCount; for (int i = 0; i < count; i++) { View child = this.GetChildAt(i); if (child.Visibility == ViewStates.Gone) { continue; } CustomLayoutParams lp = (CustomLayoutParams)child.LayoutParameters; child.Measure(GetChildMeasureSpec(widthMeasureSpec, this.PaddingLeft + this.PaddingRight, lp.Width), GetChildMeasureSpec(heightMeasureSpec, this.PaddingTop + this.PaddingBottom, lp.Height)); lp.ClearCalculatedFields(this.config.Orientation); if (this.config.Orientation == FlowLayout.HORIZONTAL) { lp.Length = child.MeasuredWidth; lp.Thickness = child.MeasuredHeight; } else { lp.Length = child.MeasuredHeight; lp.Thickness = child.MeasuredWidth; } bool newLine = lp.newLine || (modeLength != MeasureSpecMode.Unspecified && !currentLine.CanFit(child)); if (newLine) { currentLine = new LineDefinition(controlMaxLength, config); if (this.config.Orientation == VERTICAL && this.config.Direction == LAYOUT_DIRECTION_RTL) { lines.Insert(0, currentLine); } else { lines.Add(currentLine); } } if (this.config.Orientation == HORIZONTAL && this.config.Direction == LAYOUT_DIRECTION_RTL) { currentLine.AddView(0, child); } else { currentLine.AddView(child); } } this.CalculateLinesAndChildPosition(lines); int contentLength = 0; foreach (LineDefinition l in lines) { contentLength = Math.Max(contentLength, l.LineLength); } int contentThickness = currentLine.LineStartThickness + currentLine.LineThickness; int realControlLength = this.FindSize(modeLength, controlMaxLength, contentLength); int realControlThickness = this.FindSize(modeHeight, controlMaxThickness, contentThickness); this.ApplyGravityToLines(lines, realControlLength, realControlThickness); foreach (LineDefinition line in lines) { this.ApplyGravityToLine(line); this.ApplyPositionsToViews(line); } /* need to take padding into account */ int totalControlWidth = this.PaddingLeft + this.PaddingRight; int totalControlHeight = this.PaddingBottom + this.PaddingTop; if (this.config.Orientation == HORIZONTAL) { totalControlWidth += contentLength; totalControlHeight += contentThickness; } else { totalControlWidth += contentThickness; totalControlHeight += contentLength; } this.SetMeasuredDimension(ResolveSize(totalControlWidth, widthMeasureSpec), ResolveSize(totalControlHeight, heightMeasureSpec)); }