showDialog<T> function
- required BuildContext context,
- required WidgetBuilder builder,
- bool barrierDismissible = true,
- Color? barrierColor,
- String? barrierLabel,
- bool useSafeArea = true,
- RouteSettings? routeSettings,
- Offset? anchorPoint,
- TraversalEdgeBehavior? traversalEdgeBehavior,
- bool fullscreenDialog = false,
- bool? requestFocus,
- AnimationStyle? animationStyle,
Displays a Material dialog above the current contents of the app, with Material entrance and exit animations, modal barrier color, and modal barrier behavior (dialog is dismissible with a tap on the barrier).
This function takes a builder which typically builds a Dialog widget.
Content below the dialog is dimmed with a ModalBarrier. The widget
returned by the builder does not share a context with the location that
showDialog 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 and Theme 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 barrierDismissible argument is used to indicate whether tapping on the
barrier will dismiss the dialog. It is true by default and can not be null.
The barrierColor argument is used to specify the color of the modal
barrier that darkens everything below the dialog. If null the barrierColor
field from DialogThemeData is used. If that is null the default color
Colors.black54 is used.
The useSafeArea argument is used to indicate if the dialog should only
display in 'safe' areas of the screen not used by the operating system
(see SafeArea for more details). It is true by default, which means
the dialog will not overlap operating system areas. If it is set to false
the dialog will only be constrained by the screen size. It can not be null.
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. It can not be null.
The routeSettings argument is passed to showGeneralDialog,
see RouteSettings for details.
If not null, the traversalEdgeBehavior argument specifies the transfer of
focus beyond the first and the last items of the dialog route. By default,
TraversalEdgeBehavior.closedLoop is used, because it's typical for dialogs
to allow users to cycle through dialog widgets without leaving the dialog.
The requestFocus argument is used to specify whether the dialog should
request focus when shown.
If requestFocus is not provided, the value of Navigator.requestFocus is
used instead.
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,
anchorPointisOffset.zero, which will cause the content to appear in the top-left sub-screen. - for TextDirection.rtl,
anchorPointisOffset(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.
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).
Returns a Future that resolves to the value (if any) that was passed to Navigator.pop when the dialog was closed.
To create a local project with this code sample, run:
flutter create --sample=material.showDialog.1 mysample
To create a local project with this code sample, run:
flutter create --sample=material.showDialog.2 mysample
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 DialogRoute.
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=material.showDialog.3 mysample
See also:
- AlertDialog, for dialogs that have a row of buttons below a body.
- SimpleDialog, which handles the scrolling of the contents and does not show buttons below its body.
- Dialog, on which SimpleDialog and AlertDialog are based.
- showCupertinoDialog, which displays an iOS-style dialog.
- showGeneralDialog, which allows for customization of the dialog popup.
- DisplayFeatureSubScreen, which documents the specifics of how DisplayFeatures can split the screen into sub-screens.
- material.io/design/components/dialogs.html
- m3.material.io/components/dialogs
Implementation
Future<T?> showDialog<T>({
required BuildContext context,
required WidgetBuilder builder,
bool barrierDismissible = true,
Color? barrierColor,
String? barrierLabel,
bool useSafeArea = true,
bool useRootNavigator = true,
RouteSettings? routeSettings,
Offset? anchorPoint,
TraversalEdgeBehavior? traversalEdgeBehavior,
bool fullscreenDialog = false,
bool? requestFocus,
AnimationStyle? animationStyle,
}) {
assert(_debugIsActive(context));
assert(debugCheckHasMaterialLocalizations(context));
final CapturedThemes themes = InheritedTheme.capture(
from: context,
to: Navigator.of(context, rootNavigator: useRootNavigator).context,
);
return Navigator.of(context, rootNavigator: useRootNavigator).push<T>(
DialogRoute<T>(
context: context,
builder: builder,
barrierColor:
barrierColor ??
DialogTheme.of(context).barrierColor ??
Theme.of(context).dialogTheme.barrierColor ??
Colors.black54,
barrierDismissible: barrierDismissible,
barrierLabel: barrierLabel,
useSafeArea: useSafeArea,
settings: routeSettings,
themes: themes,
anchorPoint: anchorPoint,
traversalEdgeBehavior: traversalEdgeBehavior ?? TraversalEdgeBehavior.closedLoop,
requestFocus: requestFocus,
animationStyle: animationStyle,
fullscreenDialog: fullscreenDialog,
),
);
}