showGeneralDialog<T extends Object?> function
- required BuildContext context,
- required RoutePageBuilder pageBuilder,
- bool barrierDismissible = false,
- String? barrierLabel,
- Color barrierColor = const Color(0x80000000),
- Duration transitionDuration = const Duration(milliseconds: 200),
- RouteTransitionsBuilder? transitionBuilder,
- RouteSettings? routeSettings,
- Offset? anchorPoint,
Displays a dialog above the current contents of the app.
This function allows for customization of aspects of the dialog popup.
This function takes a pageBuilder
which is used to build the primary
content of the route (typically a dialog widget). Content below the dialog
is dimmed with a ModalBarrier. The widget returned by the pageBuilder
does not share a context with the location that showGeneralDialog is
originally called from. Use a StatefulBuilder or a custom
StatefulWidget if the dialog needs to update dynamically.
The context
argument is used to look up the Navigator for the
dialog. It is only used when the method is called. Its corresponding widget
can be safely removed from the tree before the dialog is closed.
The useRootNavigator
argument is used to determine whether to push the
dialog to the Navigator furthest from or nearest to the given context
.
By default, useRootNavigator
is true
and the dialog route created by
this method is pushed to the root navigator.
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)
.
The barrierDismissible
argument is used to determine whether this route
can be dismissed by tapping the modal barrier. This argument defaults
to false. If barrierDismissible
is true, a non-null barrierLabel
must be
provided.
The barrierLabel
argument is the semantic label used for a dismissible
barrier. This argument defaults to null
.
The barrierColor
argument is the color used for the modal barrier. This
argument defaults to Color(0x80000000)
.
The transitionDuration
argument is used to determine how long it takes
for the route to arrive on or leave off the screen. This argument defaults
to 200 milliseconds.
The transitionBuilder
argument is used to define how the route arrives on
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.
A DisplayFeature can split the screen into sub-screens. The closest one to
anchorPoint
is used to render the content.
If no anchorPoint
is provided, then Directionality is used:
- for TextDirection.ltr,
anchorPoint
isOffset.zero
, which will cause the content to appear in the top-left sub-screen. - for TextDirection.rtl,
anchorPoint
isOffset(double.maxFinite, 0)
, which will cause the content to appear in the top-right sub-screen.
If no anchorPoint
is provided, and there is no Directionality ancestor
widget in the tree, then the widget asserts during build in debug mode.
Returns a Future that resolves to the value (if any) that was passed to Navigator.pop when the dialog was closed.
State Restoration in Dialogs
Using this method will not enable state restoration for the dialog. In order to enable state restoration for a dialog, use Navigator.restorablePush or Navigator.restorablePushNamed with RawDialogRoute.
For more information about state restoration, see RestorationManager.
To test state restoration on Android:
- Turn on "Don't keep activities", which destroys the Android activity as soon as the user leaves it. This option should become available when Developer Options are turned on for the device.
- Run the code sample on an Android device.
- Create some in-memory state in the app on the phone, e.g. by navigating to a different screen.
- Background the Flutter app, then return to it. It will restart and restore its state.
To test state restoration on iOS:
- Open
ios/Runner.xcworkspace/
in Xcode. - (iOS 14+ only): Switch to build in profile or release mode, as launching an app from the home screen is not supported in debug mode.
- Press the Play button in Xcode to build and run the app.
- Create some in-memory state in the app on the phone, e.g. by navigating to a different screen.
- Background the app on the phone, e.g. by going back to the home screen.
- Press the Stop button in Xcode to terminate the app while running in the background.
- Open the app again on the phone (not via Xcode). It will restart and restore its state.
To create a local project with this code sample, run:
flutter create --sample=widgets.showGeneralDialog.1 mysample
import 'package:flutter/material.dart';
/// Flutter code sample for [showGeneralDialog].
void main() => runApp(const GeneralDialogApp());
class GeneralDialogApp extends StatelessWidget {
const GeneralDialogApp({super.key});
@override
Widget build(BuildContext context) {
return const MaterialApp(
restorationScopeId: 'app',
home: GeneralDialogExample(),
);
}
}
class GeneralDialogExample extends StatelessWidget {
const GeneralDialogExample({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: OutlinedButton(
onPressed: () {
/// This shows an alert dialog.
Navigator.of(context).restorablePush(_dialogBuilder);
},
child: const Text('Open Dialog'),
),
),
);
}
@pragma('vm:entry-point')
static Route<Object?> _dialogBuilder(
BuildContext context, Object? arguments) {
return RawDialogRoute<void>(
pageBuilder: (
BuildContext context,
Animation<double> animation,
Animation<double> secondaryAnimation,
) {
return const AlertDialog(title: Text('Alert!'));
},
);
}
}
See also:
- DisplayFeatureSubScreen, which documents the specifics of how DisplayFeatures can split the screen into sub-screens.
- showDialog, which displays a Material-style dialog.
- showCupertinoDialog, which displays an iOS-style dialog.
Implementation
Future<T?> showGeneralDialog<T extends Object?>({
required BuildContext context,
required RoutePageBuilder pageBuilder,
bool barrierDismissible = false,
String? barrierLabel,
Color barrierColor = const Color(0x80000000),
Duration transitionDuration = const Duration(milliseconds: 200),
RouteTransitionsBuilder? transitionBuilder,
bool useRootNavigator = true,
RouteSettings? routeSettings,
Offset? anchorPoint,
}) {
assert(!barrierDismissible || barrierLabel != null);
return Navigator.of(context, rootNavigator: useRootNavigator).push<T>(RawDialogRoute<T>(
pageBuilder: pageBuilder,
barrierDismissible: barrierDismissible,
barrierLabel: barrierLabel,
barrierColor: barrierColor,
transitionDuration: transitionDuration,
transitionBuilder: transitionBuilder,
settings: routeSettings,
anchorPoint: anchorPoint,
));
}