Added 'barrierColor' and 'useSafeArea' parameters to showDialog. (#54110)
This commit is contained in:
parent
4037e5069e
commit
d35ade4a6c
@ -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();
|
||||
|
Loading…
x
Reference in New Issue
Block a user