Unverified Commit d35ade4a authored by Darren Austin's avatar Darren Austin Committed by GitHub

Added 'barrierColor' and 'useSafeArea' parameters to showDialog. (#54110)

parent 4037e506
......@@ -871,10 +871,23 @@ Widget _buildMaterialDialogTransitions(BuildContext context, Animation<double> a
/// 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 the dialog. If `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 will mean
/// 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.
/// this method is pushed to the root navigator. It can not be `null`.
///
/// The `routeSettings` argument is passed to [showGeneralDialog],
/// see [RouteSettings] for details.
......@@ -897,7 +910,12 @@ Widget _buildMaterialDialogTransitions(BuildContext context, Animation<double> a
/// * <https://material.io/design/components/dialogs.html>
Future<T> showDialog<T>({
@required BuildContext context,
WidgetBuilder builder,
bool barrierDismissible = true,
Color barrierColor,
bool useSafeArea = true,
bool useRootNavigator = true,
RouteSettings routeSettings,
@Deprecated(
'Instead of using the "child" argument, return the child from a closure '
'provided to the "builder" argument. This will ensure that the BuildContext '
......@@ -905,11 +923,10 @@ Future<T> showDialog<T>({
'This feature was deprecated after v0.2.3.'
)
Widget child,
WidgetBuilder builder,
bool useRootNavigator = true,
RouteSettings routeSettings,
}) {
assert(child == null || builder == null);
assert(barrierDismissible != null);
assert(useSafeArea != null);
assert(useRootNavigator != null);
assert(debugCheckHasMaterialLocalizations(context));
......@@ -918,19 +935,21 @@ Future<T> showDialog<T>({
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;
}
),
Widget dialog = Builder(
builder: (BuildContext context) {
return theme != null
? Theme(data: theme, child: pageChild)
: pageChild;
}
);
if (useSafeArea) {
dialog = SafeArea(child: dialog);
}
return dialog;
},
barrierDismissible: barrierDismissible,
barrierLabel: MaterialLocalizations.of(context).modalBarrierDismissLabel,
barrierColor: Colors.black54,
barrierColor: barrierColor ?? Colors.black54,
transitionDuration: const Duration(milliseconds: 150),
transitionBuilder: _buildMaterialDialogTransitions,
useRootNavigator: useRootNavigator,
......
......@@ -344,6 +344,37 @@ void main() {
});
testWidgets('Barrier color', (WidgetTester tester) async {
await tester.pumpWidget(
const MaterialApp(
home: Center(child: Text('Test')),
),
);
final BuildContext context = tester.element(find.text('Test'));
// Test default barrier color
showDialog<void>(
context: context,
builder: (BuildContext context) {
return const Text('Dialog');
},
);
await tester.pumpAndSettle();
expect(tester.widget<ModalBarrier>(find.byType(ModalBarrier).last).color, Colors.black54);
// Dismiss it and test a custom barrier color
await tester.tapAt(const Offset(10.0, 10.0));
showDialog<void>(
context: context,
builder: (BuildContext context) {
return const Text('Dialog');
},
barrierColor: Colors.pink,
);
await tester.pumpAndSettle();
expect(tester.widget<ModalBarrier>(find.byType(ModalBarrier).last).color, Colors.pink);
});
testWidgets('Dialog hides underlying semantics tree', (WidgetTester tester) async {
final SemanticsTester semantics = SemanticsTester(tester);
const String buttonText = 'A button covered by dialog overlay';
......@@ -1020,6 +1051,47 @@ void main() {
await tester.pump();
});
testWidgets('showDialog safe area', (WidgetTester tester) async {
await tester.pumpWidget(
MaterialApp(
builder: (BuildContext context, Widget child) {
return MediaQuery(
// Set up the safe area to be 20 pixels in from each side
data: const MediaQueryData(padding: EdgeInsets.all(20.0)),
child: child,
);
},
home: const Center(child: Text('Test')),
),
);
final BuildContext context = tester.element(find.text('Test'));
// By default it should honor the safe area
showDialog<void>(
context: context,
builder: (BuildContext context) {
return const Placeholder();
},
);
await tester.pumpAndSettle();
expect(tester.getTopLeft(find.byType(Placeholder)), const Offset(20.0, 20.0));
expect(tester.getBottomRight(find.byType(Placeholder)), const Offset(780.0, 580.0));
// Dismiss it and test with useSafeArea off
await tester.tapAt(const Offset(10.0, 10.0));
showDialog<void>(
context: context,
builder: (BuildContext context) {
return const Placeholder();
},
useSafeArea: false,
);
await tester.pumpAndSettle();
// Should take up the whole screen
expect(tester.getTopLeft(find.byType(Placeholder)), const Offset(0.0, 0.0));
expect(tester.getBottomRight(find.byType(Placeholder)), const Offset(800.0, 600.0));
});
testWidgets('showDialog uses root navigator by default', (WidgetTester tester) async {
final DialogObserver rootObserver = DialogObserver();
final DialogObserver nestedObserver = DialogObserver();
......
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