From 3bbb8d8b77d3f6307b72bd108c9302146a736341 Mon Sep 17 00:00:00 2001 From: MH Johnson Date: Thu, 11 Apr 2019 09:48:35 -0400 Subject: [PATCH] [Material] Fix showDialog crasher caused by old contexts (#30754) * Fix bug, add regression test. * remove unnecessary space --- packages/flutter/lib/src/material/dialog.dart | 5 ++- .../flutter/test/material/dialog_test.dart | 38 +++++++++++++++++++ 2 files changed, 41 insertions(+), 2 deletions(-) diff --git a/packages/flutter/lib/src/material/dialog.dart b/packages/flutter/lib/src/material/dialog.dart index cba3956e6b..36f0209edc 100644 --- a/packages/flutter/lib/src/material/dialog.dart +++ b/packages/flutter/lib/src/material/dialog.dart @@ -700,11 +700,12 @@ Future showDialog({ }) { assert(child == null || builder == null); assert(debugCheckHasMaterialLocalizations(context)); + + final ThemeData theme = Theme.of(context, shadowThemeOnly: true); return showGeneralDialog( context: context, pageBuilder: (BuildContext buildContext, Animation animation, Animation secondaryAnimation) { - final ThemeData theme = Theme.of(context, shadowThemeOnly: true); - final Widget pageChild = child ?? Builder(builder: builder); + final Widget pageChild = child ?? Builder(builder: builder); return SafeArea( child: Builder( builder: (BuildContext context) { diff --git a/packages/flutter/test/material/dialog_test.dart b/packages/flutter/test/material/dialog_test.dart index c405698a6c..e63d29d818 100644 --- a/packages/flutter/test/material/dialog_test.dart +++ b/packages/flutter/test/material/dialog_test.dart @@ -607,4 +607,42 @@ void main() { expect(find.text('0'), findsNothing); expect(find.text('1'), findsNothing); }); + + // Regression test for https://github.com/flutter/flutter/issues/28505. + testWidgets('showDialog only gets Theme from context on the first call', (WidgetTester tester) async { + Widget buildFrame(Key builderKey) { + return MaterialApp( + home: Center( + child: Builder( + key: builderKey, + builder: (BuildContext outerContext) { + return RaisedButton( + onPressed: () { + showDialog( + context: outerContext, + builder: (BuildContext innerContext) { + return const AlertDialog(title: Text('Title')); + }, + ); + }, + child: const Text('Show Dialog'), + ); + }, + ), + ), + ); + } + + await tester.pumpWidget(buildFrame(UniqueKey())); + + // Open the dialog. + await tester.tap(find.byType(RaisedButton)); + await tester.pumpAndSettle(); + + // Force the Builder to be recreated (new key) which causes outerContext to + // be deactivated. If showDialog()'s implementation were to refer to + // outerContext again, it would crash. + await tester.pumpWidget(buildFrame(UniqueKey())); + await tester.pump(); + }); }