Skip to content

Commit 0214afb

Browse files
Fix the RenderFlex.computeDryBaseline implementation to match computeDistanceToActualBaseline (#149062)
Per Hixie's comment [here](flutter/flutter#145739 (comment)), keep the current behavior
1 parent c109b3c commit 0214afb

2 files changed

Lines changed: 58 additions & 5 deletions

File tree

packages/flutter/lib/src/rendering/flex.dart

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -308,6 +308,8 @@ enum CrossAxisAlignment {
308308
/// See also:
309309
///
310310
/// * [RenderBox.getDistanceToBaseline], which defines the baseline of a box.
311+
/// * [IgnoreBaseline], which can be used to ignore a child for the purpose of
312+
/// baseline alignment.
311313
baseline;
312314

313315
double _getChildCrossAxisOffset(double freeSpace, bool flipped) {
@@ -821,13 +823,17 @@ class RenderFlex extends RenderBox with ContainerRenderObjectMixin<RenderBox, Fl
821823
final double freeSpace = math.max(0.0, sizes.mainAxisFreeSpace);
822824
final bool flipMainAxis = _flipMainAxis;
823825
final (double leadingSpaceY, double spaceBetween) = mainAxisAlignment._distributeSpace(freeSpace, childCount, flipMainAxis);
824-
double y = leadingSpaceY;
825-
final (_NextChild nextChild, RenderBox? topLeftChild) = flipMainAxis ? (childBefore, lastChild) : (childAfter, firstChild);
826-
for (RenderBox? child = topLeftChild; child != null; child = nextChild(child)) {
826+
double y = flipMainAxis
827+
? leadingSpaceY + (childCount - 1) * spaceBetween + (sizes.axisSize.mainAxisExtent - sizes.mainAxisFreeSpace)
828+
: leadingSpaceY;
829+
final double directionUnit = flipMainAxis ? -1.0 : 1.0;
830+
for (RenderBox? child = firstChild; baselineOffset == BaselineOffset.noBaseline && child != null; child = childAfter(child)) {
827831
final BoxConstraints childConstraints = constraintsForChild(child);
828832
final Size childSize = child.getDryLayout(childConstraints);
829-
baselineOffset = baselineOffset.minOf(BaselineOffset(child.getDryBaseline(childConstraints, baseline)) + y);
830-
y += spaceBetween + childSize.height;
833+
final double? childBaselineOffset = child.getDryBaseline(childConstraints, baseline);
834+
final double additionalY = flipMainAxis ? - childSize.height : 0.0;
835+
baselineOffset = BaselineOffset(childBaselineOffset) + y + additionalY;
836+
y += directionUnit * (spaceBetween + childSize.height);
831837
}
832838
case Axis.horizontal:
833839
final bool flipCrossAxis = _flipCrossAxis;

packages/flutter/test/rendering/flex_test.dart

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -648,6 +648,53 @@ void main() {
648648
expect(box2.localToGlobal(Offset.zero).dy, 0.0);
649649
});
650650

651+
test('Vertical Flex Baseline', () {
652+
const BoxConstraints square = BoxConstraints.tightFor(width: 100.0, height: 100.0);
653+
final RenderConstrainedBox box1 = RenderConstrainedBox(
654+
additionalConstraints: square,
655+
child: RenderFlowBaselineTestBox()
656+
..gridCount = 1
657+
..baselinePlacer = (double height) => 10,
658+
);
659+
final RenderConstrainedBox box2 = RenderConstrainedBox(
660+
additionalConstraints: square,
661+
child: RenderFlowBaselineTestBox()
662+
..gridCount = 1
663+
..baselinePlacer = (double height) => 10,
664+
);
665+
RenderConstrainedBox filler() => RenderConstrainedBox(additionalConstraints: square);
666+
final RenderFlex flex = RenderFlex(
667+
textDirection: TextDirection.ltr,
668+
children: <RenderBox>[
669+
filler(),
670+
box1,
671+
filler(),
672+
box2,
673+
filler(),
674+
],
675+
direction: Axis.vertical,
676+
);
677+
layout(flex, phase: EnginePhase.paint);
678+
final double flexHeight = flex.size.height;
679+
680+
// We can't call the getDistanceToBaseline method directly. Check the dry
681+
// baseline instead, and in debug mode there are asserts that verify
682+
// the two methods return the same results.
683+
expect(flex.getDryBaseline(flex.constraints, TextBaseline.alphabetic), 100 + 10);
684+
685+
flex.mainAxisAlignment = MainAxisAlignment.end;
686+
pumpFrame(phase: EnginePhase.paint);
687+
expect(flex.getDryBaseline(flex.constraints, TextBaseline.alphabetic), flexHeight - 400 + 10);
688+
689+
flex.verticalDirection = VerticalDirection.up;
690+
pumpFrame(phase: EnginePhase.paint);
691+
expect(flex.getDryBaseline(flex.constraints, TextBaseline.alphabetic), 300 + 10);
692+
693+
flex.mainAxisAlignment = MainAxisAlignment.start;
694+
pumpFrame(phase: EnginePhase.paint);
695+
expect(flex.getDryBaseline(flex.constraints, TextBaseline.alphabetic), flexHeight - 200 + 10);
696+
});
697+
651698
group('Intrinsics', () {
652699
test('main axis intrinsics with RenderAspectRatio 1', () {
653700
const BoxConstraints square = BoxConstraints.tightFor(width: 100.0, height: 100.0);

0 commit comments

Comments
 (0)