Unverified Commit 231170a7 authored by Jonah Williams's avatar Jonah Williams Committed by GitHub

Replace child parameter with builder on showDialog (#15303)

* replace child parameter with builder on showDialog

* change builder parameter to WidgetBuilder

* mark child as deprecated and expand documentation to cover this and how builder should be used

* tidy comments and address some feedback

* phrasing

* move space to prev line and add //ignore comments for deprecated member use

* address comments and fix it's its

* update code samples

* adds semicolon to code snippets
parent 9a8b4602
...@@ -18,8 +18,8 @@ class _CupertinoDialogDemoState extends State<CupertinoDialogDemo> { ...@@ -18,8 +18,8 @@ class _CupertinoDialogDemoState extends State<CupertinoDialogDemo> {
void showDemoDialog<T>({ BuildContext context, Widget child }) { void showDemoDialog<T>({ BuildContext context, Widget child }) {
showDialog<T>( showDialog<T>(
context: context, context: context,
child: child,
barrierDismissible: false, barrierDismissible: false,
builder: (BuildContext context) => child,
) )
.then<Null>((T value) { // The value passed to Navigator.pop() or null. .then<Null>((T value) { // The value passed to Navigator.pop() or null.
if (value != null) { if (value != null) {
......
...@@ -68,7 +68,7 @@ class DialogDemoState extends State<DialogDemo> { ...@@ -68,7 +68,7 @@ class DialogDemoState extends State<DialogDemo> {
void showDemoDialog<T>({ BuildContext context, Widget child }) { void showDemoDialog<T>({ BuildContext context, Widget child }) {
showDialog<T>( showDialog<T>(
context: context, context: context,
child: child, builder: (BuildContext context) => child,
) )
.then<Null>((T value) { // The value passed to Navigator.pop() or null. .then<Null>((T value) { // The value passed to Navigator.pop() or null.
if (value != null) { if (value != null) {
......
...@@ -233,7 +233,8 @@ class _DrawerDemoState extends State<DrawerDemo> with TickerProviderStateMixin { ...@@ -233,7 +233,8 @@ class _DrawerDemoState extends State<DrawerDemo> with TickerProviderStateMixin {
void _onOtherAccountsTap(BuildContext context) { void _onOtherAccountsTap(BuildContext context) {
showDialog<Null>( showDialog<Null>(
context: context, context: context,
child: new AlertDialog( builder: (BuildContext context) {
return new AlertDialog(
title: const Text('Account switching not implemented.'), title: const Text('Account switching not implemented.'),
actions: <Widget>[ actions: <Widget>[
new FlatButton( new FlatButton(
...@@ -243,7 +244,8 @@ class _DrawerDemoState extends State<DrawerDemo> with TickerProviderStateMixin { ...@@ -243,7 +244,8 @@ class _DrawerDemoState extends State<DrawerDemo> with TickerProviderStateMixin {
}, },
), ),
], ],
), );
},
); );
} }
} }
...@@ -116,7 +116,8 @@ class FullScreenDialogDemoState extends State<FullScreenDialogDemo> { ...@@ -116,7 +116,8 @@ class FullScreenDialogDemoState extends State<FullScreenDialogDemo> {
return await showDialog<bool>( return await showDialog<bool>(
context: context, context: context,
child: new AlertDialog( builder: (BuildContext context) {
return new AlertDialog(
content: new Text( content: new Text(
'Discard new event?', 'Discard new event?',
style: dialogTextStyle style: dialogTextStyle
...@@ -134,8 +135,9 @@ class FullScreenDialogDemoState extends State<FullScreenDialogDemo> { ...@@ -134,8 +135,9 @@ class FullScreenDialogDemoState extends State<FullScreenDialogDemo> {
Navigator.of(context).pop(true); // Returning true to _onWillPop will pop again. Navigator.of(context).pop(true); // Returning true to _onWillPop will pop again.
} }
) )
] ],
) );
},
) ?? false; ) ?? false;
} }
......
...@@ -56,15 +56,19 @@ class _PersistentBottomSheetDemoState extends State<PersistentBottomSheetDemo> { ...@@ -56,15 +56,19 @@ class _PersistentBottomSheetDemoState extends State<PersistentBottomSheetDemo> {
void _showMessage() { void _showMessage() {
showDialog<Null>( showDialog<Null>(
context: context, context: context,
child: new AlertDialog( builder: (BuildContext context) {
return new AlertDialog(
content: const Text('You tapped the floating action button.'), content: const Text('You tapped the floating action button.'),
actions: <Widget>[ actions: <Widget>[
new FlatButton( new FlatButton(
onPressed: () { Navigator.pop(context); }, onPressed: () {
Navigator.pop(context);
},
child: const Text('OK') child: const Text('OK')
) )
] ],
) );
},
); );
} }
......
...@@ -85,7 +85,8 @@ class TextFormFieldDemoState extends State<TextFormFieldDemo> { ...@@ -85,7 +85,8 @@ class TextFormFieldDemoState extends State<TextFormFieldDemo> {
return await showDialog<bool>( return await showDialog<bool>(
context: context, context: context,
child: new AlertDialog( builder: (BuildContext context) {
return new AlertDialog(
title: const Text('This form has errors'), title: const Text('This form has errors'),
content: const Text('Really leave this form?'), content: const Text('Really leave this form?'),
actions: <Widget> [ actions: <Widget> [
...@@ -98,7 +99,8 @@ class TextFormFieldDemoState extends State<TextFormFieldDemo> { ...@@ -98,7 +99,8 @@ class TextFormFieldDemoState extends State<TextFormFieldDemo> {
onPressed: () { Navigator.of(context).pop(false); }, onPressed: () { Navigator.of(context).pop(false); },
), ),
], ],
), );
},
) ?? false; ) ?? false;
} }
......
...@@ -41,13 +41,13 @@ class UpdaterState extends State<Updater> { ...@@ -41,13 +41,13 @@ class UpdaterState extends State<Updater> {
final String updateUrl = await widget.updateUrlFetcher(); final String updateUrl = await widget.updateUrlFetcher();
if (updateUrl != null) { if (updateUrl != null) {
final bool wantsUpdate = await showDialog(context: context, child: _buildDialog()); final bool wantsUpdate = await showDialog(context: context, builder: _buildDialog);
if (wantsUpdate != null && wantsUpdate) if (wantsUpdate != null && wantsUpdate)
launch(updateUrl); launch(updateUrl);
} }
} }
Widget _buildDialog() { Widget _buildDialog(BuildContext _) {
final ThemeData theme = Theme.of(context); final ThemeData theme = Theme.of(context);
final TextStyle dialogTextStyle = final TextStyle dialogTextStyle =
theme.textTheme.subhead.copyWith(color: theme.textTheme.caption.color); theme.textTheme.subhead.copyWith(color: theme.textTheme.caption.color);
......
...@@ -95,7 +95,7 @@ class StockHomeState extends State<StockHome> { ...@@ -95,7 +95,7 @@ class StockHomeState extends State<StockHome> {
case _StockMenuItem.refresh: case _StockMenuItem.refresh:
showDialog<Null>( showDialog<Null>(
context: context, context: context,
child: new _NotImplementedDialog() builder: (BuildContext context) => new _NotImplementedDialog(),
); );
break; break;
case _StockMenuItem.speedUp: case _StockMenuItem.speedUp:
......
...@@ -67,7 +67,8 @@ class StockSettingsState extends State<StockSettings> { ...@@ -67,7 +67,8 @@ class StockSettingsState extends State<StockSettings> {
case StockMode.pessimistic: case StockMode.pessimistic:
showDialog<bool>( showDialog<bool>(
context: context, context: context,
child: new AlertDialog( builder: (BuildContext context) {
return new AlertDialog(
title: const Text('Change mode?'), title: const Text('Change mode?'),
content: const Text('Optimistic mode means everything is awesome. Are you sure you can handle that?'), content: const Text('Optimistic mode means everything is awesome. Are you sure you can handle that?'),
actions: <Widget>[ actions: <Widget>[
...@@ -83,8 +84,9 @@ class StockSettingsState extends State<StockSettings> { ...@@ -83,8 +84,9 @@ class StockSettingsState extends State<StockSettings> {
Navigator.pop(context, true); Navigator.pop(context, true);
} }
), ),
] ],
) );
},
).then<void>(_handleOptimismChanged); ).then<void>(_handleOptimismChanged);
break; break;
} }
......
...@@ -153,13 +153,15 @@ void showAboutDialog({ ...@@ -153,13 +153,15 @@ void showAboutDialog({
}) { }) {
showDialog<Null>( showDialog<Null>(
context: context, context: context,
child: new AboutDialog( builder: (BuildContext context) {
return new AboutDialog(
applicationName: applicationName, applicationName: applicationName,
applicationVersion: applicationVersion, applicationVersion: applicationVersion,
applicationIcon: applicationIcon, applicationIcon: applicationIcon,
applicationLegalese: applicationLegalese, applicationLegalese: applicationLegalese,
children: children children: children,
) );
}
); );
} }
......
...@@ -1042,6 +1042,6 @@ Future<DateTime> showDatePicker({ ...@@ -1042,6 +1042,6 @@ Future<DateTime> showDatePicker({
return await showDialog<DateTime>( return await showDialog<DateTime>(
context: context, context: context,
child: child, builder: (BuildContext context) => child,
); );
} }
...@@ -96,7 +96,8 @@ class Dialog extends StatelessWidget { ...@@ -96,7 +96,8 @@ class Dialog extends StatelessWidget {
/// return showDialog<Null>( /// return showDialog<Null>(
/// context: context, /// context: context,
/// barrierDismissible: false, // user must tap button! /// barrierDismissible: false, // user must tap button!
/// child: new AlertDialog( /// builder: (BuildContext context) {
/// return new AlertDialog(
/// title: new Text('Rewind and remember'), /// title: new Text('Rewind and remember'),
/// content: new SingleChildScrollView( /// content: new SingleChildScrollView(
/// child: new ListBody( /// child: new ListBody(
...@@ -114,7 +115,8 @@ class Dialog extends StatelessWidget { ...@@ -114,7 +115,8 @@ class Dialog extends StatelessWidget {
/// }, /// },
/// ), /// ),
/// ], /// ],
/// ), /// );
/// },
/// ); /// );
/// } /// }
/// ``` /// ```
...@@ -301,7 +303,8 @@ class SimpleDialogOption extends StatelessWidget { ...@@ -301,7 +303,8 @@ class SimpleDialogOption extends StatelessWidget {
/// Future<Null> _askedToLead() async { /// Future<Null> _askedToLead() async {
/// switch (await showDialog<Department>( /// switch (await showDialog<Department>(
/// context: context, /// context: context,
/// child: new SimpleDialog( /// builder: (BuildContext context) {
/// return new SimpleDialog(
/// title: const Text('Select assignment'), /// title: const Text('Select assignment'),
/// children: <Widget>[ /// children: <Widget>[
/// new SimpleDialogOption( /// new SimpleDialogOption(
...@@ -313,7 +316,8 @@ class SimpleDialogOption extends StatelessWidget { ...@@ -313,7 +316,8 @@ class SimpleDialogOption extends StatelessWidget {
/// child: const Text('State department'), /// child: const Text('State department'),
/// ), /// ),
/// ], /// ],
/// ), /// );
/// }
/// )) { /// )) {
/// case Department.treasury: /// case Department.treasury:
/// // Let's go. /// // Let's go.
...@@ -457,13 +461,18 @@ class _DialogRoute<T> extends PopupRoute<T> { ...@@ -457,13 +461,18 @@ class _DialogRoute<T> extends PopupRoute<T> {
/// Displays a dialog above the current contents of the app. /// Displays a dialog above the current contents of the app.
/// ///
/// This function typically receives a [Dialog] widget as its child argument. /// This function takes a `builder` which typically builds a [Dialog] widget.
/// Content below the dialog is dimmed with a [ModalBarrier]. /// Content below the dialog is dimmed with a [ModalBarrier]. This widget 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 `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 /// 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. /// widget can be safely removed from the tree before the dialog is closed.
/// ///
/// The `child` argument is deprecated, and should be replaced with `builder`.
///
/// Returns a [Future] that resolves to the value (if any) that was passed to /// Returns a [Future] that resolves to the value (if any) that was passed to
/// [Navigator.pop] when the dialog was closed. /// [Navigator.pop] when the dialog was closed.
/// ///
...@@ -481,10 +490,16 @@ class _DialogRoute<T> extends PopupRoute<T> { ...@@ -481,10 +490,16 @@ class _DialogRoute<T> extends PopupRoute<T> {
Future<T> showDialog<T>({ Future<T> showDialog<T>({
@required BuildContext context, @required BuildContext context,
bool barrierDismissible: true, bool barrierDismissible: true,
@required Widget child, @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.'
) Widget child,
WidgetBuilder builder,
}) { }) {
assert(child == null || builder == null); // ignore: deprecated_member_use
return Navigator.of(context, rootNavigator: true).push(new _DialogRoute<T>( return Navigator.of(context, rootNavigator: true).push(new _DialogRoute<T>(
child: child, child: child ?? new Builder(builder: builder), // ignore: deprecated_member_use
theme: Theme.of(context, shadowThemeOnly: true), theme: Theme.of(context, shadowThemeOnly: true),
barrierDismissible: barrierDismissible, barrierDismissible: barrierDismissible,
barrierLabel: MaterialLocalizations.of(context).modalBarrierDismissLabel, barrierLabel: MaterialLocalizations.of(context).modalBarrierDismissLabel,
......
...@@ -1645,7 +1645,7 @@ Future<TimeOfDay> showTimePicker({ ...@@ -1645,7 +1645,7 @@ Future<TimeOfDay> showTimePicker({
return await showDialog<TimeOfDay>( return await showDialog<TimeOfDay>(
context: context, context: context,
child: new _TimePickerDialog(initialTime: initialTime), builder: (BuildContext context) => new _TimePickerDialog(initialTime: initialTime),
); );
} }
......
...@@ -19,7 +19,8 @@ void main() { ...@@ -19,7 +19,8 @@ void main() {
onPressed: () { onPressed: () {
showDialog<Null>( showDialog<Null>(
context: context, context: context,
child: new CupertinoAlertDialog( builder: (BuildContext context) {
return new CupertinoAlertDialog(
title: const Text('The title'), title: const Text('The title'),
content: const Text('The content'), content: const Text('The content'),
actions: <Widget>[ actions: <Widget>[
...@@ -35,7 +36,8 @@ void main() { ...@@ -35,7 +36,8 @@ void main() {
child: const Text('Delete'), child: const Text('Delete'),
), ),
], ],
), );
},
); );
}, },
child: const Text('Go'), child: const Text('Go'),
...@@ -110,7 +112,7 @@ void main() { ...@@ -110,7 +112,7 @@ void main() {
onPressed: () { onPressed: () {
showDialog<Null>( showDialog<Null>(
context: context, context: context,
child: new Builder(builder: (BuildContext context) { builder: (BuildContext context) {
return new MediaQuery( return new MediaQuery(
data: MediaQuery.of(context).copyWith(textScaleFactor: 3.0), data: MediaQuery.of(context).copyWith(textScaleFactor: 3.0),
child: new CupertinoAlertDialog( child: new CupertinoAlertDialog(
...@@ -128,7 +130,7 @@ void main() { ...@@ -128,7 +130,7 @@ void main() {
scrollController: scrollController, scrollController: scrollController,
), ),
); );
}), },
); );
}, },
child: const Text('Go'), child: const Text('Go'),
......
...@@ -23,7 +23,8 @@ void main() { ...@@ -23,7 +23,8 @@ void main() {
onPressed: () { onPressed: () {
showDialog<Null>( showDialog<Null>(
context: context, context: context,
child: new AlertDialog( builder: (BuildContext context) {
return new AlertDialog(
content: new Container( content: new Container(
height: 5000.0, height: 5000.0,
width: 300.0, width: 300.0,
...@@ -36,8 +37,9 @@ void main() { ...@@ -36,8 +37,9 @@ void main() {
}, },
child: const Text('OK') child: const Text('OK')
) )
] ],
) );
},
); );
} }
) )
...@@ -71,11 +73,13 @@ void main() { ...@@ -71,11 +73,13 @@ void main() {
onPressed: () { onPressed: () {
showDialog<Null>( showDialog<Null>(
context: context, context: context,
child: const AlertDialog( builder: (BuildContext context) {
return const AlertDialog(
title: const Text('Title'), title: const Text('Title'),
content: const Text('Y'), content: const Text('Y'),
actions: const <Widget>[ ], actions: const <Widget>[ ],
), );
},
); );
}, },
), ),
...@@ -116,7 +120,8 @@ void main() { ...@@ -116,7 +120,8 @@ void main() {
final Future<int> result = showDialog( final Future<int> result = showDialog(
context: context, context: context,
child: new SimpleDialog( builder: (BuildContext context) {
return new SimpleDialog(
title: const Text('Title'), title: const Text('Title'),
children: <Widget>[ children: <Widget>[
new SimpleDialogOption( new SimpleDialogOption(
...@@ -129,7 +134,8 @@ void main() { ...@@ -129,7 +134,8 @@ void main() {
child: const Text('Second option'), child: const Text('Second option'),
), ),
], ],
), );
},
); );
await tester.pumpAndSettle(const Duration(seconds: 1)); await tester.pumpAndSettle(const Duration(seconds: 1));
...@@ -157,12 +163,14 @@ void main() { ...@@ -157,12 +163,14 @@ void main() {
showDialog<Null>( showDialog<Null>(
context: context, context: context,
child: new Container( builder: (BuildContext context) {
return new Container(
width: 100.0, width: 100.0,
height: 100.0, height: 100.0,
alignment: Alignment.center, alignment: Alignment.center,
child: const Text('Dialog1'), child: const Text('Dialog1'),
), );
},
); );
await tester.pumpAndSettle(const Duration(seconds: 1)); await tester.pumpAndSettle(const Duration(seconds: 1));
...@@ -177,12 +185,14 @@ void main() { ...@@ -177,12 +185,14 @@ void main() {
showDialog<Null>( showDialog<Null>(
context: context, context: context,
barrierDismissible: false, barrierDismissible: false,
child: new Container( builder: (BuildContext context) {
return new Container(
width: 100.0, width: 100.0,
height: 100.0, height: 100.0,
alignment: Alignment.center, alignment: Alignment.center,
child: const Text('Dialog2'), child: const Text('Dialog2'),
), );
},
); );
await tester.pumpAndSettle(const Duration(seconds: 1)); await tester.pumpAndSettle(const Duration(seconds: 1));
...@@ -219,7 +229,9 @@ void main() { ...@@ -219,7 +229,9 @@ void main() {
const String alertText = 'A button in an overlay alert'; const String alertText = 'A button in an overlay alert';
showDialog<Null>( showDialog<Null>(
context: context, context: context,
child: const AlertDialog(title: const Text(alertText)), builder: (BuildContext context) {
return const AlertDialog(title: const Text(alertText));
},
); );
await tester.pumpAndSettle(const Duration(seconds: 1)); await tester.pumpAndSettle(const Duration(seconds: 1));
...@@ -260,12 +272,10 @@ void main() { ...@@ -260,12 +272,10 @@ void main() {
showDialog<Null>( showDialog<Null>(
context: outerContext, context: outerContext,
barrierDismissible: false, barrierDismissible: false,
child: new Builder(
builder: (BuildContext context) { builder: (BuildContext context) {
dialogContext = context; dialogContext = context;
return new Container(); return new Container();
}, },
),
); );
await tester.pump(); await tester.pump();
......
...@@ -110,7 +110,7 @@ void main() { ...@@ -110,7 +110,7 @@ void main() {
showDialog<Null>( showDialog<Null>(
context: context, context: context,
child: const SimpleDialog(title: const Text('Dialog')), builder: (BuildContext context) => const SimpleDialog(title: const Text('Dialog')),
); );
await tester.pump(); await tester.pump();
......
...@@ -200,7 +200,7 @@ void main() { ...@@ -200,7 +200,7 @@ void main() {
onPressed: () { onPressed: () {
showDialog<Null>( showDialog<Null>(
context: context, context: context,
child: const Text('dialog'), builder: (BuildContext context) => const Text('dialog'),
); );
}, },
child: const Text('SHOW'), child: const Text('SHOW'),
...@@ -232,12 +232,14 @@ void main() { ...@@ -232,12 +232,14 @@ void main() {
onTap: () { onTap: () {
showDialog<Null>( showDialog<Null>(
context: context, context: context,
child: const Scaffold( builder: (BuildContext context) {
return const Scaffold(
body: const SizedBox( body: const SizedBox(
width: 200.0, width: 200.0,
height: 200.0, height: 200.0,
), ),
) );
},
); );
}, },
child: const Text('SHOW'), child: const Text('SHOW'),
......
...@@ -86,7 +86,7 @@ void main() { ...@@ -86,7 +86,7 @@ void main() {
onPressed: () { onPressed: () {
showDialog<Null>( showDialog<Null>(
context: context, context: context,
child: new SamplePage(), builder: (BuildContext context) => new SamplePage(),
); );
}, },
), ),
...@@ -185,7 +185,8 @@ void main() { ...@@ -185,7 +185,8 @@ void main() {
Future<bool> showYesNoAlert(BuildContext context) { Future<bool> showYesNoAlert(BuildContext context) {
return showDialog<bool>( return showDialog<bool>(
context: context, context: context,
child: new AlertDialog( builder: (BuildContext context) {
return new AlertDialog(
actions: <Widget> [ actions: <Widget> [
new FlatButton( new FlatButton(
child: const Text('YES'), child: const Text('YES'),
...@@ -196,7 +197,8 @@ void main() { ...@@ -196,7 +197,8 @@ void main() {
onPressed: () { Navigator.of(context).pop(false); }, onPressed: () { Navigator.of(context).pop(false); },
), ),
], ],
), );
},
); );
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment