From 76394630acecade01b6eac22225c47b4075d4996 Mon Sep 17 00:00:00 2001 From: Adam Barth Date: Fri, 24 Feb 2017 12:25:33 -0800 Subject: [PATCH] Add barrierDismissable argument to showDialog (#8397) In some situations, dialogs don't want the barrier to be dismissable. Fixes #8354 --- packages/flutter/lib/src/material/dialog.dart | 16 ++++-- .../flutter/test/material/dialog_test.dart | 57 +++++++++++++++++++ 2 files changed, 68 insertions(+), 5 deletions(-) diff --git a/packages/flutter/lib/src/material/dialog.dart b/packages/flutter/lib/src/material/dialog.dart index 76cbbba9c3..70da99e635 100644 --- a/packages/flutter/lib/src/material/dialog.dart +++ b/packages/flutter/lib/src/material/dialog.dart @@ -316,9 +316,12 @@ class SimpleDialog extends StatelessWidget { class _DialogRoute extends PopupRoute { _DialogRoute({ - this.child, - this.theme, - }); + @required this.theme, + bool barrierDismissable: true, + @required this.child, + }) : _barrierDismissable = barrierDismissable { + assert(barrierDismissable != null); + } final Widget child; final ThemeData theme; @@ -327,7 +330,8 @@ class _DialogRoute extends PopupRoute { Duration get transitionDuration => const Duration(milliseconds: 150); @override - bool get barrierDismissable => true; + bool get barrierDismissable => _barrierDismissable; + final bool _barrierDismissable; @override Color get barrierColor => Colors.black54; @@ -364,10 +368,12 @@ class _DialogRoute extends PopupRoute { /// * Future showDialog({ @required BuildContext context, - @required Widget child + bool barrierDismissable: true, + @required Widget child, }) { return Navigator.push(context, new _DialogRoute( child: child, theme: Theme.of(context, shadowThemeOnly: true), + barrierDismissable: barrierDismissable, )); } diff --git a/packages/flutter/test/material/dialog_test.dart b/packages/flutter/test/material/dialog_test.dart index 7253878644..fb2a7a6cd2 100644 --- a/packages/flutter/test/material/dialog_test.dart +++ b/packages/flutter/test/material/dialog_test.dart @@ -137,4 +137,61 @@ void main() { expect(await result, equals(42)); }); + + testWidgets('Barrier dismissable', (WidgetTester tester) async { + await tester.pumpWidget( + new MaterialApp( + home: new Material( + child: new Center( + child: new RaisedButton( + onPressed: null, + child: new Text('Go'), + ), + ), + ), + ), + ); + + BuildContext context = tester.element(find.text('Go')); + + showDialog( + context: context, + child: new Container( + width: 100.0, + height: 100.0, + alignment: FractionalOffset.center, + child: new Text('Dialog1'), + ), + ); + + await tester.pumpUntilNoTransientCallbacks(const Duration(seconds: 1)); + expect(find.text('Dialog1'), findsOneWidget); + + // Tap on the barrier. + await tester.tapAt(const Point(10.0, 10.0)); + + await tester.pumpUntilNoTransientCallbacks(const Duration(seconds: 1)); + expect(find.text('Dialog1'), findsNothing); + + showDialog( + context: context, + barrierDismissable: false, + child: new Container( + width: 100.0, + height: 100.0, + alignment: FractionalOffset.center, + child: new Text('Dialog2'), + ), + ); + + await tester.pumpUntilNoTransientCallbacks(const Duration(seconds: 1)); + expect(find.text('Dialog2'), findsOneWidget); + + // Tap on the barrier, which shouldn't do anything this time. + await tester.tapAt(const Point(10.0, 10.0)); + + await tester.pumpUntilNoTransientCallbacks(const Duration(seconds: 1)); + expect(find.text('Dialog2'), findsOneWidget); + + }); }