Created
May 12, 2020 07:52
-
-
Save wei-spring/e93522ab68ff9aae0221f08ba03b1bf0 to your computer and use it in GitHub Desktop.
Full width dialog for flutter .
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Copyright 2015 The Chromium Authors. All rights reserved. | |
// Use of this source code is governed by a BSD-style license that can be | |
// found in the LICENSE file. | |
import 'dart:async'; | |
import 'package:flutter/foundation.dart'; | |
import 'package:flutter/material.dart'; | |
import 'package:flutter/widgets.dart'; | |
// Examples can assume: | |
// enum Department { treasury, state } | |
// BuildContext context; | |
/// A material design dialog. | |
/// | |
/// This dialog widget does not have any opinion about the contents of the | |
/// dialog. Rather than using this widget directly, consider using [AlertDialog] | |
/// or [SimpleDialog], which implement specific kinds of material design | |
/// dialogs. | |
/// | |
/// See also: | |
/// | |
/// * [AlertDialog], for dialogs that have a message and some buttons. | |
/// * [SimpleDialog], for dialogs that offer a variety of options. | |
/// * [showDialog], which actually displays the dialog and returns its result. | |
/// * <https://material.io/design/components/dialogs.html> | |
class ZhDialog extends StatelessWidget { | |
/// Creates a dialog. | |
/// | |
/// Typically used in conjunction with [showDialog]. | |
const ZhDialog({ | |
Key key, | |
this.backgroundColor, | |
this.elevation, | |
this.insetAnimationDuration = const Duration(milliseconds: 100), | |
this.insetAnimationCurve = Curves.decelerate, | |
this.shape, | |
this.child, | |
}) : super(key: key); | |
/// {@template flutter.material.dialog.backgroundColor} | |
/// The background color of the surface of this [Dialog]. | |
/// | |
/// This sets the [Material.color] on this [Dialog]'s [Material]. | |
/// | |
/// If `null`, [ThemeData.cardColor] is used. | |
/// {@endtemplate} | |
final Color backgroundColor; | |
/// {@template flutter.material.dialog.elevation} | |
/// The z-coordinate of this [Dialog]. | |
/// | |
/// If null then [DialogTheme.elevation] is used, and if that's null then the | |
/// dialog's elevation is 24.0. | |
/// {@endtemplate} | |
/// {@macro flutter.material.material.elevation} | |
final double elevation; | |
/// {@template flutter.material.dialog.insetAnimationDuration} | |
/// The duration of the animation to show when the system keyboard intrudes | |
/// into the space that the dialog is placed in. | |
/// | |
/// Defaults to 100 milliseconds. | |
/// {@endtemplate} | |
final Duration insetAnimationDuration; | |
/// {@template flutter.material.dialog.insetAnimationCurve} | |
/// The curve to use for the animation shown when the system keyboard intrudes | |
/// into the space that the dialog is placed in. | |
/// | |
/// Defaults to [Curves.decelerate]. | |
/// {@endtemplate} | |
final Curve insetAnimationCurve; | |
/// {@template flutter.material.dialog.shape} | |
/// The shape of this dialog's border. | |
/// | |
/// Defines the dialog's [Material.shape]. | |
/// | |
/// The default shape is a [RoundedRectangleBorder] with a radius of 2.0. | |
/// {@endtemplate} | |
final ShapeBorder shape; | |
/// The widget below this widget in the tree. | |
/// | |
/// {@macro flutter.widgets.child} | |
final Widget child; | |
// TODO(johnsonmh): Update default dialog border radius to 4.0 to match material spec. | |
static const RoundedRectangleBorder _defaultDialogShape = | |
RoundedRectangleBorder( | |
borderRadius: BorderRadius.all(Radius.circular(2.0))); | |
static const double _defaultElevation = 24.0; | |
@override | |
Widget build(BuildContext context) { | |
final DialogTheme dialogTheme = DialogTheme.of(context); | |
return AnimatedPadding( | |
padding: MediaQuery.of(context).viewInsets + | |
const EdgeInsets.symmetric(horizontal: 0, vertical: 24.0), | |
duration: insetAnimationDuration, | |
curve: insetAnimationCurve, | |
child: MediaQuery.removeViewInsets( | |
removeLeft: true, | |
removeTop: true, | |
removeRight: true, | |
removeBottom: true, | |
context: context, | |
child: Center( | |
child: ConstrainedBox( | |
constraints: const BoxConstraints(minWidth: 280.0), | |
child: Material( | |
color: backgroundColor ?? | |
dialogTheme.backgroundColor ?? | |
Theme.of(context).dialogBackgroundColor, | |
elevation: | |
elevation ?? dialogTheme.elevation ?? _defaultElevation, | |
shape: shape ?? dialogTheme.shape ?? _defaultDialogShape, | |
type: MaterialType.card, | |
child: child, | |
), | |
), | |
), | |
), | |
); | |
} | |
} | |
/// A material design alert dialog. | |
/// | |
/// An alert dialog informs the user about situations that require | |
/// acknowledgement. An alert dialog has an optional title and an optional list | |
/// of actions. The title is displayed above the content and the actions are | |
/// displayed below the content. | |
/// | |
/// {@youtube 560 315 https://www.youtube.com/watch?v=75CsnyRXf5I} | |
/// | |
/// If the content is too large to fit on the screen vertically, the dialog will | |
/// display the title and the actions and let the content overflow, which is | |
/// rarely desired. Consider using a scrolling widget for [content], such as | |
/// [SingleChildScrollView], to avoid overflow. (However, be aware that since | |
/// [AlertDialog] tries to size itself using the intrinsic dimensions of its | |
/// children, widgets such as [ListView], [GridView], and [CustomScrollView], | |
/// which use lazy viewports, will not work. If this is a problem, consider | |
/// using [Dialog] directly.) | |
/// | |
/// For dialogs that offer the user a choice between several options, consider | |
/// using a [SimpleDialog]. | |
/// | |
/// Typically passed as the child widget to [showDialog], which displays the | |
/// dialog. | |
/// | |
/// {@tool sample} | |
/// | |
/// This snippet shows a method in a [State] which, when called, displays a dialog box | |
/// and returns a [Future] that completes when the dialog is dismissed. | |
/// | |
/// ```dart | |
/// Future<void> _neverSatisfied() async { | |
/// return showDialog<void>( | |
/// context: context, | |
/// barrierDismissible: false, // user must tap button! | |
/// builder: (BuildContext context) { | |
/// return AlertDialog( | |
/// title: Text('Rewind and remember'), | |
/// content: SingleChildScrollView( | |
/// child: ListBody( | |
/// children: <Widget>[ | |
/// Text('You will never be satisfied.'), | |
/// Text('You\’re like me. I’m never satisfied.'), | |
/// ], | |
/// ), | |
/// ), | |
/// actions: <Widget>[ | |
/// FlatButton( | |
/// child: Text('Regret'), | |
/// onPressed: () { | |
/// Navigator.of(context).pop(); | |
/// }, | |
/// ), | |
/// ], | |
/// ); | |
/// }, | |
/// ); | |
/// } | |
/// ``` | |
/// {@end-tool} | |
/// | |
/// See also: | |
/// | |
/// * [SimpleDialog], which handles the scrolling of the contents but has no [actions]. | |
/// * [Dialog], on which [AlertDialog] and [SimpleDialog] are based. | |
/// * [CupertinoAlertDialog], an iOS-styled alert dialog. | |
/// * [showDialog], which actually displays the dialog and returns its result. | |
/// * <https://material.io/design/components/dialogs.html#alert-dialog> | |
class ZhAlertDialog extends StatelessWidget { | |
/// Creates an alert dialog. | |
/// | |
/// Typically used in conjunction with [showDialog]. | |
/// | |
/// The [contentPadding] must not be null. The [titlePadding] defaults to | |
/// null, which implies a default that depends on the values of the other | |
/// properties. See the documentation of [titlePadding] for details. | |
const ZhAlertDialog({ | |
Key key, | |
this.title, | |
this.titlePadding, | |
this.titleTextStyle, | |
this.content, | |
this.contentPadding = const EdgeInsets.fromLTRB(24.0, 20.0, 24.0, 24.0), | |
this.contentTextStyle, | |
this.actions, | |
this.backgroundColor, | |
this.elevation, | |
this.semanticLabel, | |
this.shape, | |
}) : assert(contentPadding != null), | |
super(key: key); | |
/// The (optional) title of the dialog is displayed in a large font at the top | |
/// of the dialog. | |
/// | |
/// Typically a [Text] widget. | |
final Widget title; | |
/// Padding around the title. | |
/// | |
/// If there is no title, no padding will be provided. Otherwise, this padding | |
/// is used. | |
/// | |
/// This property defaults to providing 24 pixels on the top, left, and right | |
/// of the title. If the [content] is not null, then no bottom padding is | |
/// provided (but see [contentPadding]). If it _is_ null, then an extra 20 | |
/// pixels of bottom padding is added to separate the [title] from the | |
/// [actions]. | |
final EdgeInsetsGeometry titlePadding; | |
/// Style for the text in the [title] of this [AlertDialog]. | |
/// | |
/// If null, [DialogTheme.titleTextStyle] is used, if that's null, defaults to | |
/// [ThemeData.textTheme.title]. | |
final TextStyle titleTextStyle; | |
/// The (optional) content of the dialog is displayed in the center of the | |
/// dialog in a lighter font. | |
/// | |
/// Typically this is a [SingleChildScrollView] that contains the dialog's | |
/// message. As noted in the [AlertDialog] documentation, it's important | |
/// to use a [SingleChildScrollView] if there's any risk that the content | |
/// will not fit. | |
final Widget content; | |
/// Padding around the content. | |
/// | |
/// If there is no content, no padding will be provided. Otherwise, padding of | |
/// 20 pixels is provided above the content to separate the content from the | |
/// title, and padding of 24 pixels is provided on the left, right, and bottom | |
/// to separate the content from the other edges of the dialog. | |
final EdgeInsetsGeometry contentPadding; | |
/// Style for the text in the [content] of this [AlertDialog]. | |
/// | |
/// If null, [DialogTheme.contentTextStyle] is used, if that's null, defaults | |
/// to [ThemeData.textTheme.subhead]. | |
final TextStyle contentTextStyle; | |
/// The (optional) set of actions that are displayed at the bottom of the | |
/// dialog. | |
/// | |
/// Typically this is a list of [FlatButton] widgets. | |
/// | |
/// These widgets will be wrapped in a [ButtonBar], which introduces 8 pixels | |
/// of padding on each side. | |
/// | |
/// If the [title] is not null but the [content] _is_ null, then an extra 20 | |
/// pixels of padding is added above the [ButtonBar] to separate the [title] | |
/// from the [actions]. | |
final List<Widget> actions; | |
/// {@macro flutter.material.dialog.backgroundColor} | |
final Color backgroundColor; | |
/// {@macro flutter.material.dialog.elevation} | |
/// {@macro flutter.material.material.elevation} | |
final double elevation; | |
/// The semantic label of the dialog used by accessibility frameworks to | |
/// announce screen transitions when the dialog is opened and closed. | |
/// | |
/// If this label is not provided, a semantic label will be inferred from the | |
/// [title] if it is not null. If there is no title, the label will be taken | |
/// from [MaterialLocalizations.alertDialogLabel]. | |
/// | |
/// See also: | |
/// | |
/// * [SemanticsConfiguration.isRouteName], for a description of how this | |
/// value is used. | |
final String semanticLabel; | |
/// {@macro flutter.material.dialog.shape} | |
final ShapeBorder shape; | |
@override | |
Widget build(BuildContext context) { | |
assert(debugCheckHasMaterialLocalizations(context)); | |
final ThemeData theme = Theme.of(context); | |
final DialogTheme dialogTheme = DialogTheme.of(context); | |
String label = semanticLabel; | |
if (title == null) { | |
switch (theme.platform) { | |
case TargetPlatform.iOS: | |
label = semanticLabel; | |
break; | |
case TargetPlatform.android: | |
case TargetPlatform.fuchsia: | |
label = semanticLabel ?? | |
MaterialLocalizations.of(context)?.alertDialogLabel; | |
} | |
} | |
Widget dialogChild = IntrinsicWidth( | |
child: Column( | |
mainAxisSize: MainAxisSize.min, | |
crossAxisAlignment: CrossAxisAlignment.stretch, | |
children: <Widget>[ | |
if (title != null) | |
Padding( | |
padding: titlePadding ?? | |
EdgeInsets.fromLTRB( | |
24.0, 24.0, 24.0, content == null ? 20.0 : 0.0), | |
child: DefaultTextStyle( | |
style: titleTextStyle ?? | |
dialogTheme.titleTextStyle ?? | |
theme.textTheme.title, | |
child: Semantics( | |
child: title, | |
namesRoute: true, | |
container: true, | |
), | |
), | |
), | |
if (content != null) | |
Flexible( | |
child: Padding( | |
padding: contentPadding, | |
child: DefaultTextStyle( | |
style: contentTextStyle ?? | |
dialogTheme.contentTextStyle ?? | |
theme.textTheme.subhead, | |
child: content, | |
), | |
), | |
), | |
if (actions != null) | |
ButtonBar( | |
children: actions, | |
), | |
], | |
), | |
); | |
if (label != null) | |
dialogChild = Semantics( | |
namesRoute: true, | |
label: label, | |
child: dialogChild, | |
); | |
return Dialog( | |
backgroundColor: backgroundColor, | |
elevation: elevation, | |
shape: shape, | |
child: dialogChild, | |
); | |
} | |
} | |
/// An option used in a [SimpleDialog]. | |
/// | |
/// A simple dialog offers the user a choice between several options. This | |
/// widget is commonly used to represent each of the options. If the user | |
/// selects this option, the widget will call the [onPressed] callback, which | |
/// typically uses [Navigator.pop] to close the dialog. | |
/// | |
/// The padding on a [SimpleDialogOption] is configured to combine with the | |
/// default [SimpleDialog.contentPadding] so that each option ends up 8 pixels | |
/// from the other vertically, with 20 pixels of spacing between the dialog's | |
/// title and the first option, and 24 pixels of spacing between the last option | |
/// and the bottom of the dialog. | |
/// | |
/// {@tool sample} | |
/// | |
/// ```dart | |
/// SimpleDialogOption( | |
/// onPressed: () { Navigator.pop(context, Department.treasury); }, | |
/// child: const Text('Treasury department'), | |
/// ) | |
/// ``` | |
/// {@end-tool} | |
/// | |
/// See also: | |
/// | |
/// * [SimpleDialog], for a dialog in which to use this widget. | |
/// * [showDialog], which actually displays the dialog and returns its result. | |
/// * [FlatButton], which are commonly used as actions in other kinds of | |
/// dialogs, such as [AlertDialog]s. | |
/// * <https://material.io/design/components/dialogs.html#simple-dialog> | |
class ZhSimpleDialogOption extends StatelessWidget { | |
/// Creates an option for a [SimpleDialog]. | |
const ZhSimpleDialogOption({ | |
Key key, | |
this.onPressed, | |
this.child, | |
}) : super(key: key); | |
/// The callback that is called when this option is selected. | |
/// | |
/// If this is set to null, the option cannot be selected. | |
/// | |
/// When used in a [SimpleDialog], this will typically call [Navigator.pop] | |
/// with a value for [showDialog] to complete its future with. | |
final VoidCallback onPressed; | |
/// The widget below this widget in the tree. | |
/// | |
/// Typically a [Text] widget. | |
final Widget child; | |
@override | |
Widget build(BuildContext context) { | |
return InkWell( | |
onTap: onPressed, | |
child: Padding( | |
padding: const EdgeInsets.symmetric(vertical: 8.0, horizontal: 24.0), | |
child: child, | |
), | |
); | |
} | |
} | |
/// A simple material design dialog. | |
/// | |
/// A simple dialog offers the user a choice between several options. A simple | |
/// dialog has an optional title that is displayed above the choices. | |
/// | |
/// Choices are normally represented using [SimpleDialogOption] widgets. If | |
/// other widgets are used, see [contentPadding] for notes regarding the | |
/// conventions for obtaining the spacing expected by Material Design. | |
/// | |
/// For dialogs that inform the user about a situation, consider using an | |
/// [AlertDialog]. | |
/// | |
/// Typically passed as the child widget to [showDialog], which displays the | |
/// dialog. | |
/// | |
/// {@tool sample} | |
/// | |
/// In this example, the user is asked to select between two options. These | |
/// options are represented as an enum. The [showDialog] method here returns | |
/// a [Future] that completes to a value of that enum. If the user cancels | |
/// the dialog (e.g. by hitting the back button on Android, or tapping on the | |
/// mask behind the dialog) then the future completes with the null value. | |
/// | |
/// The return value in this example is used as the index for a switch statement. | |
/// One advantage of using an enum as the return value and then using that to | |
/// drive a switch statement is that the analyzer will flag any switch statement | |
/// that doesn't mention every value in the enum. | |
/// | |
/// ```dart | |
/// Future<void> _askedToLead() async { | |
/// switch (await showDialog<Department>( | |
/// context: context, | |
/// builder: (BuildContext context) { | |
/// return SimpleDialog( | |
/// title: const Text('Select assignment'), | |
/// children: <Widget>[ | |
/// SimpleDialogOption( | |
/// onPressed: () { Navigator.pop(context, Department.treasury); }, | |
/// child: const Text('Treasury department'), | |
/// ), | |
/// SimpleDialogOption( | |
/// onPressed: () { Navigator.pop(context, Department.state); }, | |
/// child: const Text('State department'), | |
/// ), | |
/// ], | |
/// ); | |
/// } | |
/// )) { | |
/// case Department.treasury: | |
/// // Let's go. | |
/// // ... | |
/// break; | |
/// case Department.state: | |
/// // ... | |
/// break; | |
/// } | |
/// } | |
/// ``` | |
/// {@end-tool} | |
/// | |
/// See also: | |
/// | |
/// * [SimpleDialogOption], which are options used in this type of dialog. | |
/// * [AlertDialog], for dialogs that have a row of buttons below the body. | |
/// * [Dialog], on which [SimpleDialog] and [AlertDialog] are based. | |
/// * [showDialog], which actually displays the dialog and returns its result. | |
/// * <https://material.io/design/components/dialogs.html#simple-dialog> | |
class ZhSimpleDialog extends StatelessWidget { | |
/// Creates a simple dialog. | |
/// | |
/// Typically used in conjunction with [showDialog]. | |
/// | |
/// The [titlePadding] and [contentPadding] arguments must not be null. | |
const ZhSimpleDialog({ | |
Key key, | |
this.title, | |
this.titlePadding = const EdgeInsets.fromLTRB(24.0, 24.0, 24.0, 0.0), | |
this.children, | |
this.contentPadding = const EdgeInsets.fromLTRB(0.0, 12.0, 0.0, 16.0), | |
this.backgroundColor, | |
this.elevation, | |
this.semanticLabel, | |
this.shape, | |
}) : assert(titlePadding != null), | |
assert(contentPadding != null), | |
super(key: key); | |
/// The (optional) title of the dialog is displayed in a large font at the top | |
/// of the dialog. | |
/// | |
/// Typically a [Text] widget. | |
final Widget title; | |
/// Padding around the title. | |
/// | |
/// If there is no title, no padding will be provided. | |
/// | |
/// By default, this provides the recommend Material Design padding of 24 | |
/// pixels around the left, top, and right edges of the title. | |
/// | |
/// See [contentPadding] for the conventions regarding padding between the | |
/// [title] and the [children]. | |
final EdgeInsetsGeometry titlePadding; | |
/// The (optional) content of the dialog is displayed in a | |
/// [SingleChildScrollView] underneath the title. | |
/// | |
/// Typically a list of [SimpleDialogOption]s. | |
final List<Widget> children; | |
/// Padding around the content. | |
/// | |
/// By default, this is 12 pixels on the top and 16 pixels on the bottom. This | |
/// is intended to be combined with children that have 24 pixels of padding on | |
/// the left and right, and 8 pixels of padding on the top and bottom, so that | |
/// the content ends up being indented 20 pixels from the title, 24 pixels | |
/// from the bottom, and 24 pixels from the sides. | |
/// | |
/// The [SimpleDialogOption] widget uses such padding. | |
/// | |
/// If there is no [title], the [contentPadding] should be adjusted so that | |
/// the top padding ends up being 24 pixels. | |
final EdgeInsetsGeometry contentPadding; | |
/// {@macro flutter.material.dialog.backgroundColor} | |
final Color backgroundColor; | |
/// {@macro flutter.material.dialog.elevation} | |
/// {@macro flutter.material.material.elevation} | |
final double elevation; | |
/// The semantic label of the dialog used by accessibility frameworks to | |
/// announce screen transitions when the dialog is opened and closed. | |
/// | |
/// If this label is not provided, a semantic label will be inferred from the | |
/// [title] if it is not null. If there is no title, the label will be taken | |
/// from [MaterialLocalizations.dialogLabel]. | |
/// | |
/// See also: | |
/// | |
/// * [SemanticsConfiguration.isRouteName], for a description of how this | |
/// value is used. | |
final String semanticLabel; | |
/// {@macro flutter.material.dialog.shape} | |
final ShapeBorder shape; | |
@override | |
Widget build(BuildContext context) { | |
assert(debugCheckHasMaterialLocalizations(context)); | |
final ThemeData theme = Theme.of(context); | |
String label = semanticLabel; | |
if (title == null) { | |
switch (theme.platform) { | |
case TargetPlatform.iOS: | |
label = semanticLabel; | |
break; | |
case TargetPlatform.android: | |
case TargetPlatform.fuchsia: | |
label = | |
semanticLabel ?? MaterialLocalizations.of(context)?.dialogLabel; | |
} | |
} | |
Widget dialogChild = IntrinsicWidth( | |
stepWidth: 56.0, | |
child: ConstrainedBox( | |
constraints: const BoxConstraints(minWidth: 280.0), | |
child: Column( | |
mainAxisSize: MainAxisSize.min, | |
crossAxisAlignment: CrossAxisAlignment.stretch, | |
children: <Widget>[ | |
if (title != null) | |
Padding( | |
padding: titlePadding, | |
child: DefaultTextStyle( | |
style: theme.textTheme.title, | |
child: Semantics(namesRoute: true, child: title), | |
), | |
), | |
if (children != null) | |
Flexible( | |
child: SingleChildScrollView( | |
padding: contentPadding, | |
child: ListBody(children: children), | |
), | |
), | |
], | |
), | |
), | |
); | |
if (label != null) | |
dialogChild = Semantics( | |
namesRoute: true, | |
label: label, | |
child: dialogChild, | |
); | |
return Dialog( | |
backgroundColor: backgroundColor, | |
elevation: elevation, | |
shape: shape, | |
child: dialogChild, | |
); | |
} | |
} | |
Widget _buildMaterialDialogTransitions( | |
BuildContext context, | |
Animation<double> animation, | |
Animation<double> secondaryAnimation, | |
Widget child) { | |
return FadeTransition( | |
opacity: CurvedAnimation( | |
parent: animation, | |
curve: Curves.easeOut, | |
), | |
child: child, | |
); | |
} | |
/// 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 `child` argument is deprecated, and should be replaced with `builder`. | |
/// | |
/// 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 `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)`. | |
/// | |
/// Returns a [Future] that resolves to the value (if any) that was passed to | |
/// [Navigator.pop] when the dialog was closed. | |
/// | |
/// 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. | |
/// * <https://material.io/design/components/dialogs.html> | |
Future<T> showZhDialog<T>({ | |
@required | |
BuildContext context, | |
bool barrierDismissible = true, | |
@Deprecated( | |
'Instead of using the "child" argument, return the child from a closure ' | |
'provided to the "builder" argument. This will ensure that the BuildContext ' | |
'is appropriate for widgets built in the dialog. ' | |
'This feature was deprecated after v0.2.3.') | |
Widget child, | |
WidgetBuilder builder, | |
bool useRootNavigator = true, | |
}) { | |
assert(child == null || builder == null); | |
assert(useRootNavigator != null); | |
assert(debugCheckHasMaterialLocalizations(context)); | |
final ThemeData theme = Theme.of(context, shadowThemeOnly: true); | |
return showGeneralDialog( | |
context: context, | |
pageBuilder: (BuildContext buildContext, Animation<double> animation, | |
Animation<double> secondaryAnimation) { | |
final Widget pageChild = child ?? Builder(builder: builder); | |
return SafeArea( | |
child: Builder(builder: (BuildContext context) { | |
return theme != null | |
? Theme(data: theme, child: pageChild) | |
: pageChild; | |
}), | |
); | |
}, | |
barrierDismissible: barrierDismissible, | |
barrierLabel: MaterialLocalizations.of(context).modalBarrierDismissLabel, | |
barrierColor: Colors.black54, | |
transitionDuration: const Duration(milliseconds: 150), | |
transitionBuilder: _buildMaterialDialogTransitions, | |
useRootNavigator: useRootNavigator, | |
); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment