Pass RouteSettings into all callers of showGeneralDialog. (#51525)
diff --git a/packages/flutter/lib/src/cupertino/route.dart b/packages/flutter/lib/src/cupertino/route.dart index 8ecbaec..d0f4768 100644 --- a/packages/flutter/lib/src/cupertino/route.dart +++ b/packages/flutter/lib/src/cupertino/route.dart
@@ -976,6 +976,7 @@ @required BuildContext context, @required WidgetBuilder builder, bool useRootNavigator = true, + RouteSettings routeSettings, }) { assert(builder != null); assert(useRootNavigator != null); @@ -990,5 +991,6 @@ }, transitionBuilder: _buildCupertinoDialogTransitions, useRootNavigator: useRootNavigator, + routeSettings: routeSettings, ); }
diff --git a/packages/flutter/lib/src/material/about.dart b/packages/flutter/lib/src/material/about.dart index c794090..f4a8291 100644 --- a/packages/flutter/lib/src/material/about.dart +++ b/packages/flutter/lib/src/material/about.dart
@@ -223,8 +223,8 @@ /// The licenses shown on the [LicensePage] are those returned by the /// [LicenseRegistry] API, which can be used to add more licenses to the list. /// -/// The [context] and [useRootNavigator] arguments are passed to [showDialog], -/// the documentation for which discusses how it is used. +/// The [context], [useRootNavigator] and [routeSettings] arguments are passed to +/// [showDialog], the documentation for which discusses how it is used. void showAboutDialog({ @required BuildContext context, String applicationName, @@ -233,6 +233,7 @@ String applicationLegalese, List<Widget> children, bool useRootNavigator = true, + RouteSettings routeSettings, }) { assert(context != null); assert(useRootNavigator != null); @@ -248,6 +249,7 @@ children: children, ); }, + routeSettings: routeSettings, ); }
diff --git a/packages/flutter/lib/src/material/date_picker.dart b/packages/flutter/lib/src/material/date_picker.dart index 9c63ae2..22e81ba 100644 --- a/packages/flutter/lib/src/material/date_picker.dart +++ b/packages/flutter/lib/src/material/date_picker.dart
@@ -1086,8 +1086,8 @@ /// provided by [Directionality]. If both [locale] and [textDirection] are not /// null, [textDirection] overrides the direction chosen for the [locale]. /// -/// The [context] and [useRootNavigator] arguments are passed to [showDialog], -/// the documentation for which discusses how it is used. +/// The [context], [useRootNavigator] and [routeSettings] arguments are passed to +/// [showDialog], the documentation for which discusses how it is used. /// /// The [builder] parameter can be used to wrap the dialog widget /// to add inherited widgets like [Theme]. @@ -1137,6 +1137,7 @@ TextDirection textDirection, TransitionBuilder builder, bool useRootNavigator = true, + RouteSettings routeSettings, }) async { assert(initialDate != null); assert(firstDate != null); @@ -1182,5 +1183,6 @@ builder: (BuildContext context) { return builder == null ? child : builder(context, child); }, + routeSettings: routeSettings, ); }
diff --git a/packages/flutter/lib/src/material/dialog.dart b/packages/flutter/lib/src/material/dialog.dart index 4c3ecc5..340a1d6 100644 --- a/packages/flutter/lib/src/material/dialog.dart +++ b/packages/flutter/lib/src/material/dialog.dart
@@ -872,6 +872,9 @@ /// By default, `useRootNavigator` is `true` and the dialog route created by /// this method is pushed to the root navigator. /// +/// The `routeSettings` argument is passed to [showGeneralDialog], +/// see [RouteSettings] for details. +/// /// If the application has multiple [Navigator] objects, it may be necessary to /// call `Navigator.of(context, rootNavigator: true).pop(result)` to close the /// dialog rather than just `Navigator.pop(context, result)`. @@ -900,6 +903,7 @@ Widget child, WidgetBuilder builder, bool useRootNavigator = true, + RouteSettings routeSettings, }) { assert(child == null || builder == null); assert(useRootNavigator != null); @@ -926,5 +930,6 @@ transitionDuration: const Duration(milliseconds: 150), transitionBuilder: _buildMaterialDialogTransitions, useRootNavigator: useRootNavigator, + routeSettings: routeSettings, ); }
diff --git a/packages/flutter/lib/src/material/time_picker.dart b/packages/flutter/lib/src/material/time_picker.dart index f41ebc0..42e36a5 100644 --- a/packages/flutter/lib/src/material/time_picker.dart +++ b/packages/flutter/lib/src/material/time_picker.dart
@@ -1749,8 +1749,8 @@ /// ``` /// {@end-tool} /// -/// The [context] and [useRootNavigator] arguments are passed to [showDialog], -/// the documentation for which discusses how it is used. +/// The [context], [useRootNavigator] and [routeSettings] arguments are passed to +/// [showDialog], the documentation for which discusses how it is used. /// /// The [builder] parameter can be used to wrap the dialog widget /// to add inherited widgets like [Localizations.override], @@ -1799,6 +1799,7 @@ @required TimeOfDay initialTime, TransitionBuilder builder, bool useRootNavigator = true, + RouteSettings routeSettings, }) async { assert(context != null); assert(initialTime != null); @@ -1812,6 +1813,7 @@ builder: (BuildContext context) { return builder == null ? dialog : builder(context, dialog); }, + routeSettings: routeSettings, ); }
diff --git a/packages/flutter/lib/src/widgets/routes.dart b/packages/flutter/lib/src/widgets/routes.dart index 2ea1dd2..f0ee871 100644 --- a/packages/flutter/lib/src/widgets/routes.dart +++ b/packages/flutter/lib/src/widgets/routes.dart
@@ -1727,6 +1727,9 @@ /// and leaves off the screen. By default, the transition is a linear fade of /// the page's contents. /// +/// The `routeSettings` will be used in the construction of the dialog's route. +/// See [RouteSettings] for more details. +/// /// Returns a [Future] that resolves to the value (if any) that was passed to /// [Navigator.pop] when the dialog was closed. /// @@ -1743,6 +1746,7 @@ Duration transitionDuration, RouteTransitionsBuilder transitionBuilder, bool useRootNavigator = true, + RouteSettings routeSettings, }) { assert(pageBuilder != null); assert(useRootNavigator != null); @@ -1754,6 +1758,7 @@ barrierColor: barrierColor, transitionDuration: transitionDuration, transitionBuilder: transitionBuilder, + settings: routeSettings, )); }
diff --git a/packages/flutter/test/material/dialog_test.dart b/packages/flutter/test/material/dialog_test.dart index 79f606e..2bd1161 100644 --- a/packages/flutter/test/material/dialog_test.dart +++ b/packages/flutter/test/material/dialog_test.dart
@@ -1170,6 +1170,60 @@ expect(content.localToGlobal(Offset.zero), equals(contentOriginalOffset)); }); }); + + testWidgets('Dialog with RouteSettings', (WidgetTester tester) async { + RouteSettings currentRouteSetting; + + await tester.pumpWidget( + MaterialApp( + navigatorObservers: <NavigatorObserver>[ + _ClosureNavigatorObserver(onDidChange: (Route<dynamic> newRoute) { + currentRouteSetting = newRoute?.settings; + }) + ], + home: const Material( + child: Center( + child: RaisedButton( + onPressed: null, + child: Text('Go'), + ), + ), + ), + ), + ); + + final BuildContext context = tester.element(find.text('Go')); + const RouteSettings exampleSetting = RouteSettings(name: 'simple'); + + final Future<int> result = showDialog<int>( + context: context, + builder: (BuildContext context) { + return SimpleDialog( + title: const Text('Title'), + children: <Widget>[ + SimpleDialogOption( + child: const Text('X'), + onPressed: () { + Navigator.of(context).pop(); + }, + ), + ], + ); + }, + routeSettings: exampleSetting, + ); + + await tester.pumpAndSettle(); + expect(find.text('Title'), findsOneWidget); + expect(currentRouteSetting, exampleSetting); + + await tester.tap(find.text('X')); + await tester.pumpAndSettle(); + + expect(await result, isNull); + await tester.pumpAndSettle(); + expect(currentRouteSetting?.name, '/'); + }); } class DialogObserver extends NavigatorObserver { @@ -1183,3 +1237,21 @@ super.didPush(route, previousRoute); } } + +class _ClosureNavigatorObserver extends NavigatorObserver { + _ClosureNavigatorObserver({@required this.onDidChange}); + + final void Function(Route<dynamic> newRoute) onDidChange; + + @override + void didPush(Route<dynamic> route, Route<dynamic> previousRoute) => onDidChange(route); + + @override + void didPop(Route<dynamic> route, Route<dynamic> previousRoute) => onDidChange(previousRoute); + + @override + void didRemove(Route<dynamic> route, Route<dynamic> previousRoute) => onDidChange(previousRoute); + + @override + void didReplace({Route<dynamic> newRoute, Route<dynamic> oldRoute}) => onDidChange(newRoute); +}