diff --git a/packages/flutter/lib/src/widgets/overflow_bar.dart b/packages/flutter/lib/src/widgets/overflow_bar.dart index 08429541d8..acf6f912d9 100644 --- a/packages/flutter/lib/src/widgets/overflow_bar.dart +++ b/packages/flutter/lib/src/widgets/overflow_bar.dart @@ -510,17 +510,25 @@ class _RenderOverflowBar extends RenderBox } 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 9fe528c72a..77bcaead21 100644 --- a/packages/flutter/test/widgets/overflow_bar_test.dart +++ b/packages/flutter/test/widgets/overflow_bar_test.dart @@ -234,4 +234,41 @@ void main() { 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: [ + 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); + }); }