Corrected OverflowBar layout when it is wider that its intrinsic width (#82380)
diff --git a/packages/flutter/lib/src/widgets/overflow_bar.dart b/packages/flutter/lib/src/widgets/overflow_bar.dart
index 0842954..acf6f91 100644
--- a/packages/flutter/lib/src/widgets/overflow_bar.dart
+++ b/packages/flutter/lib/src/widgets/overflow_bar.dart
@@ -510,17 +510,25 @@
}
size = constraints.constrain(Size(constraints.maxWidth, y - overflowSpacing));
} else {
- // Default horizontal layout
- child = rtl ? lastChild : firstChild;
- RenderBox? nextChild() => rtl ? childBefore(child!) : childAfter(child!);
- double x = 0;
+ // Default horizontal layout.
+ size = constraints.constrain(Size(actualWidth, maxChildHeight));
+ child = firstChild;
+ double x = rtl ? size.width - child!.size.width : 0;
while (child != null) {
final _OverflowBarParentData childParentData = child.parentData! as _OverflowBarParentData;
childParentData.offset = Offset(x, (maxChildHeight - child.size.height) / 2);
- x += child.size.width + spacing;
- child = nextChild();
+ // x is the horizontal origin of child. To advance x to the next child's
+ // origin for LTR: add the width of the current child. To advance x to
+ // the origin of the next child for RTL: subtract the width of the next
+ // child (if there is one).
+ if (!rtl) {
+ x += child.size.width + spacing;
+ }
+ child = childAfter(child);
+ if (rtl && child != null) {
+ x -= child.size.width + spacing;
+ }
}
- size = constraints.constrain(Size(actualWidth, maxChildHeight));
}
}
diff --git a/packages/flutter/test/widgets/overflow_bar_test.dart b/packages/flutter/test/widgets/overflow_bar_test.dart
index 9fe528c..77bcaea 100644
--- a/packages/flutter/test/widgets/overflow_bar_test.dart
+++ b/packages/flutter/test/widgets/overflow_bar_test.dart
@@ -234,4 +234,41 @@
await tester.pumpWidget(buildFrame(maxWidth: 150));
expect(tester.getSize(find.byType(OverflowBar)).height, 166); // 166 = 50 + 8 + 25 + 8 + 75
});
+
+
+ testWidgets('OverflowBar is wider that its intrinsic width', (WidgetTester tester) async {
+ final Key key0 = UniqueKey();
+ final Key key1 = UniqueKey();
+ final Key key2 = UniqueKey();
+
+ Widget buildFrame(TextDirection textDirection) {
+ return Directionality(
+ textDirection: textDirection,
+ child: SizedBox(
+ width: 800,
+ // intrinsic width = 50 + 10 + 60 + 10 + 70 = 200
+ child: OverflowBar(
+ spacing: 10,
+ children: <Widget>[
+ SizedBox(key: key0, width: 50, height: 50),
+ SizedBox(key: key1, width: 60, height: 50),
+ SizedBox(key: key2, width: 70, height: 50),
+ ],
+ ),
+ ),
+ );
+ }
+
+ await tester.pumpWidget(buildFrame(TextDirection.ltr));
+ expect(tester.getSize(find.byType(OverflowBar)), const Size(800.0, 600.0));
+ expect(tester.getTopLeft(find.byKey(key0)).dx, 0);
+ expect(tester.getTopLeft(find.byKey(key1)).dx, 60);
+ expect(tester.getTopLeft(find.byKey(key2)).dx, 130);
+
+ await tester.pumpWidget(buildFrame(TextDirection.rtl));
+ expect(tester.getSize(find.byType(OverflowBar)), const Size(800.0, 600.0));
+ expect(tester.getTopLeft(find.byKey(key0)).dx, 750);
+ expect(tester.getTopLeft(find.byKey(key1)).dx, 680);
+ expect(tester.getTopLeft(find.byKey(key2)).dx, 600);
+ });
}