protected override void performLayout() { BoxConstraints constraints = this.constraints; bool hasLeading = leading != null; bool hasSubtitle = subtitle != null; bool hasTrailing = trailing != null; bool isTwoLine = !isThreeLine && hasSubtitle; bool isOneLine = !isThreeLine && !hasSubtitle; BoxConstraints maxIconHeightConstrains = new BoxConstraints( maxHeight: isDense ? 48.0f : 56.0f ); BoxConstraints looseConstraints = constraints.loosen(); BoxConstraints iconConstraints = looseConstraints.enforce(maxIconHeightConstrains); float tileWidth = looseConstraints.maxWidth; Size leadingSize = _layoutBox(leading, iconConstraints); Size trailingSize = _layoutBox(trailing, iconConstraints); D.assert( tileWidth != leadingSize.width, () => "Leading widget consumes entire width. Please use a sized widget." ); D.assert( tileWidth != trailingSize.width, () => "Trailing widget consumes entire width. Please use a sized widget." ); float titleStart = hasLeading ? Mathf.Max(_minLeadingWidth, leadingSize.width) + _horizontalTitleGap : 0.0f; BoxConstraints textConstraints = looseConstraints.tighten( width: tileWidth - titleStart - (hasTrailing ? trailingSize.width + _horizontalTitleGap : 0.0f)); Size titleSize = _layoutBox(title, textConstraints); Size subtitleSize = _layoutBox(subtitle, textConstraints); float titleBaseline = 0.0f; float subtitleBaseline = 0.0f; if (isTwoLine) { titleBaseline = isDense ? 28.0f : 32.0f; subtitleBaseline = isDense ? 48.0f : 52.0f; } else if (isThreeLine) { titleBaseline = isDense ? 22.0f : 28.0f; subtitleBaseline = isDense ? 42.0f : 48.0f; } else { D.assert(isOneLine); } float defaultTileHeight = _defaultTileHeight; float tileHeight = 0.0f; float titleY = 0.0f; float subtitleY = 0.0f; if (!hasSubtitle) { tileHeight = Mathf.Max(defaultTileHeight, titleSize.height + 2.0f * _minVerticalPadding); titleY = (tileHeight - titleSize.height) / 2.0f; } else { D.assert(subtitleBaselineType != null); titleY = titleBaseline - _boxBaseline(title, titleBaselineType); subtitleY = subtitleBaseline - _boxBaseline(subtitle, subtitleBaselineType ?? TextBaseline.alphabetic); tileHeight = defaultTileHeight; float titleOverlap = titleY + titleSize.height - subtitleY; if (titleOverlap > 0.0f) { titleY -= titleOverlap / 2.0f; subtitleY += titleOverlap / 2.0f; } if (titleY < _minVerticalPadding || (subtitleY + subtitleSize.height + _minVerticalPadding) > tileHeight) { tileHeight = titleSize.height + subtitleSize.height + 2.0f * _minVerticalPadding; titleY = _minVerticalPadding; subtitleY = titleSize.height + _minVerticalPadding; } } float leadingY; float trailingY; if (tileHeight > 72.0f) { leadingY = 16.0f; trailingY = 16.0f; } else { leadingY = Mathf.Min((tileHeight - leadingSize.height) / 2.0f, 16.0f); trailingY = (tileHeight - trailingSize.height) / 2.0f; } if (hasLeading) { _positionBox(leading, new Offset(0.0f, leadingY)); } _positionBox(title, new Offset(titleStart, titleY)); if (hasSubtitle) { _positionBox(subtitle, new Offset(titleStart, subtitleY)); } if (hasTrailing) { _positionBox(trailing, new Offset(tileWidth - trailingSize.width, trailingY)); } size = constraints.constrain(new Size(tileWidth, tileHeight)); D.assert(size.width == constraints.constrainWidth(tileWidth)); D.assert(size.height == constraints.constrainHeight(tileHeight)); }
protected override void performLayout() { BoxConstraints constraints = this.constraints; _resolve(); D.assert(_resolvedAlignment != null); _hasVisualOverflow = false; bool hasNonPositionedChildren = false; if (childCount == 0) { size = constraints.biggest; D.assert(size.isFinite); return; } float width = constraints.minWidth; float height = constraints.minHeight; BoxConstraints nonPositionedConstraints = null; switch (fit) { case StackFit.loose: nonPositionedConstraints = constraints.loosen(); break; case StackFit.expand: nonPositionedConstraints = BoxConstraints.tight(constraints.biggest); break; case StackFit.passthrough: nonPositionedConstraints = constraints; break; } D.assert(nonPositionedConstraints != null); RenderBox child = firstChild; while (child != null) { StackParentData childParentData = child.parentData as StackParentData; D.assert(childParentData != null); if (!childParentData.isPositioned) { hasNonPositionedChildren = true; child.layout(nonPositionedConstraints, parentUsesSize: true); Size childSize = child.size; width = Mathf.Max(width, childSize.width); height = Mathf.Max(height, childSize.height); } child = childParentData.nextSibling; } if (hasNonPositionedChildren) { size = new Size(width, height); D.assert(size.width == constraints.constrainWidth(width)); D.assert(size.height == constraints.constrainHeight(height)); } else { size = constraints.biggest; } D.assert(size.isFinite); child = firstChild; while (child != null) { StackParentData childParentData = child.parentData as StackParentData; if (!childParentData.isPositioned) { childParentData.offset = _resolvedAlignment.alongOffset(size - child.size as Offset); } else { _hasVisualOverflow = layoutPositionedChild(child, childParentData, size, _resolvedAlignment) || _hasVisualOverflow; } D.assert(child.parentData == childParentData); child = childParentData.nextSibling; } }