From 4bd47ce60ce8a17e7bd8557abe2a01fe21cbcd37 Mon Sep 17 00:00:00 2001 From: Hans Muller Date: Fri, 25 Jun 2021 10:47:36 -0700 Subject: [PATCH] Added AlertDialog.actionsAlignment OverflowBar configuration (#85260) Added AlertDialog.actionsAlignment OverflowBar configuration. --- packages/flutter/lib/src/material/dialog.dart | 30 ++++++---- .../flutter/test/material/dialog_test.dart | 58 ++++++++++++++++++- 2 files changed, 74 insertions(+), 14 deletions(-) diff --git a/packages/flutter/lib/src/material/dialog.dart b/packages/flutter/lib/src/material/dialog.dart index 901da98a62..9f44dcb5d7 100644 --- a/packages/flutter/lib/src/material/dialog.dart +++ b/packages/flutter/lib/src/material/dialog.dart @@ -276,6 +276,7 @@ class AlertDialog extends StatelessWidget { this.contentTextStyle, this.actions, this.actionsPadding = EdgeInsets.zero, + this.actionsAlignment, this.actionsOverflowDirection, this.actionsOverflowButtonSpacing, this.buttonPadding, @@ -383,6 +384,15 @@ class AlertDialog extends StatelessWidget { /// * [ButtonBar], which [actions] configures to lay itself out. final EdgeInsetsGeometry actionsPadding; + /// Defines the horizontal layout of the [actions] according to the same + /// rules as for [Row.mainAxisAlignment]. + /// + /// This parameter is passed along to the dialog's [OverflowBar]. + /// + /// If this parameter is null (the default) then [MainAxisAlignment.end] + /// is used. + final MainAxisAlignment? actionsAlignment; + /// The vertical direction of [actions] if the children overflow /// horizontally. /// @@ -534,21 +544,17 @@ class AlertDialog extends StatelessWidget { ); } - if (actions != null) { final double spacing = (buttonPadding?.horizontal ?? 16) / 2; actionsWidget = Padding( - padding: actionsPadding, - child: Container( - alignment: AlignmentDirectional.centerEnd, - padding: EdgeInsets.all(spacing), - child: OverflowBar( - spacing: spacing, - overflowAlignment: OverflowBarAlignment.end, - overflowDirection: actionsOverflowDirection ?? VerticalDirection.down, - overflowSpacing: actionsOverflowButtonSpacing ?? 0, - children: actions!, - ), + padding: actionsPadding.add(EdgeInsets.all(spacing)), + child: OverflowBar( + alignment: actionsAlignment ?? MainAxisAlignment.end, + spacing: spacing, + overflowAlignment: OverflowBarAlignment.end, + overflowDirection: actionsOverflowDirection ?? VerticalDirection.down, + overflowSpacing: actionsOverflowButtonSpacing ?? 0, + children: actions!, ), ); } diff --git a/packages/flutter/test/material/dialog_test.dart b/packages/flutter/test/material/dialog_test.dart index 6096750539..2a736f935f 100644 --- a/packages/flutter/test/material/dialog_test.dart +++ b/packages/flutter/test/material/dialog_test.dart @@ -50,7 +50,7 @@ RenderParagraph _getTextRenderObjectFromDialog(WidgetTester tester, String text) // is now a Container with an OverflowBar child. The Container's size and location // match the original ButtonBar's size and location. Finder _findButtonBar() { - return find.ancestor(of: find.byType(OverflowBar), matching: find.byType(Container)).first; + return find.ancestor(of: find.byType(OverflowBar), matching: find.byType(Padding)).first; } const ShapeBorder _defaultDialogShape = RoundedRectangleBorder(borderRadius: BorderRadius.all(Radius.circular(4.0))); @@ -517,6 +517,8 @@ void main() { child: const Text('button'), ), ], + // The OverflowBar is inset by the buttonPadding/2 + actionsPadding + buttonPadding: EdgeInsets.zero, actionsPadding: const EdgeInsets.all(30.0), // custom padding value ); @@ -536,7 +538,7 @@ void main() { matching: find.byType(Material), ).first, ); - final Size actionsSize = tester.getSize(_findButtonBar()); + final Size actionsSize = tester.getSize(find.byType(OverflowBar)); expect(actionsSize.width, dialogSize.width - (30.0 * 2)); }); @@ -2066,6 +2068,58 @@ void main() { await tester.restoreFrom(restorationData); expect(find.byType(AlertDialog), findsOneWidget); }, skip: isBrowser); // https://github.com/flutter/flutter/issues/33615 + + testWidgets('AlertDialog.actionsAlignment', (WidgetTester tester) async { + final Key actionKey = UniqueKey(); + + Widget buildFrame(MainAxisAlignment? alignment) { + return MaterialApp( + home: Scaffold( + body: AlertDialog( + content: const SizedBox(width: 800), + actionsAlignment: alignment, + actions: [SizedBox(key: actionKey, width: 20, height: 20)], + buttonPadding: EdgeInsets.zero, + insetPadding: EdgeInsets.zero, + ), + ), + ); + } + + // Default configuration + await tester.pumpWidget(buildFrame(null)); + expect(tester.getTopLeft(find.byType(AlertDialog)).dx, 0); + expect(tester.getTopRight(find.byType(AlertDialog)).dx, 800); + expect(tester.getSize(find.byType(OverflowBar)).width, 800); + expect(tester.getTopLeft(find.byKey(actionKey)).dx, 800 - 20); + expect(tester.getTopRight(find.byKey(actionKey)).dx, 800); + + // All possible alginment values + + await tester.pumpWidget(buildFrame(MainAxisAlignment.start)); + expect(tester.getTopLeft(find.byKey(actionKey)).dx, 0); + expect(tester.getTopRight(find.byKey(actionKey)).dx, 20); + + await tester.pumpWidget(buildFrame(MainAxisAlignment.center)); + expect(tester.getTopLeft(find.byKey(actionKey)).dx, (800 - 20) / 2); + expect(tester.getTopRight(find.byKey(actionKey)).dx, (800 - 20) / 2 + 20); + + await tester.pumpWidget(buildFrame(MainAxisAlignment.end)); + expect(tester.getTopLeft(find.byKey(actionKey)).dx, 800 - 20); + expect(tester.getTopRight(find.byKey(actionKey)).dx, 800); + + await tester.pumpWidget(buildFrame(MainAxisAlignment.spaceBetween)); + expect(tester.getTopLeft(find.byKey(actionKey)).dx, 0); + expect(tester.getTopRight(find.byKey(actionKey)).dx, 20); + + await tester.pumpWidget(buildFrame(MainAxisAlignment.spaceAround)); + expect(tester.getTopLeft(find.byKey(actionKey)).dx, (800 - 20) / 2); + expect(tester.getTopRight(find.byKey(actionKey)).dx, (800 - 20) / 2 + 20); + + await tester.pumpWidget(buildFrame(MainAxisAlignment.spaceEvenly)); + expect(tester.getTopLeft(find.byKey(actionKey)).dx, (800 - 20) / 2); + expect(tester.getTopRight(find.byKey(actionKey)).dx, (800 - 20) / 2 + 20); + }); } class _RestorableDialogTestWidget extends StatelessWidget {