Unverified Commit 28b5cc38 authored by Edman P. Anjos's avatar Edman P. Anjos Committed by GitHub

Pad CupertinoAlertDialog with MediaQuery viewInsets (#42967)

Fixes #42049.
parent 9093cf15
......@@ -129,6 +129,8 @@ class CupertinoAlertDialog extends StatelessWidget {
this.actions = const <Widget>[],
this.scrollController,
this.actionScrollController,
this.insetAnimationDuration = const Duration(milliseconds: 100),
this.insetAnimationCurve = Curves.decelerate,
}) : assert(actions != null),
super(key: key);
......@@ -173,6 +175,12 @@ class CupertinoAlertDialog extends StatelessWidget {
/// section when it is long.
final ScrollController actionScrollController;
/// {@macro flutter.material.dialog.insetAnimationDuration}
final Duration insetAnimationDuration;
/// {@macro flutter.material.dialog.insetAnimationCurve}
final Curve insetAnimationCurve;
Widget _buildContent(BuildContext context) {
final List<Widget> children = <Widget>[
if (title != null || content != null)
......@@ -224,22 +232,35 @@ class CupertinoAlertDialog extends StatelessWidget {
),
child: LayoutBuilder(
builder: (BuildContext context, BoxConstraints constraints) {
return Center(
child: Container(
margin: const EdgeInsets.symmetric(vertical: _kEdgePadding),
width: isInAccessibilityMode
? _kAccessibilityCupertinoDialogWidth
: _kCupertinoDialogWidth,
child: CupertinoPopupSurface(
isSurfacePainted: false,
child: Semantics(
namesRoute: true,
scopesRoute: true,
explicitChildNodes: true,
label: localizations.alertDialogLabel,
child: _CupertinoDialogRenderWidget(
contentSection: _buildContent(context),
actionsSection: _buildActions(),
return AnimatedPadding(
padding: MediaQuery.of(context).viewInsets +
const EdgeInsets.symmetric(horizontal: 40.0, vertical: 24.0),
duration: insetAnimationDuration,
curve: insetAnimationCurve,
child: MediaQuery.removeViewInsets(
removeLeft: true,
removeTop: true,
removeRight: true,
removeBottom: true,
context: context,
child: Center(
child: Container(
margin: const EdgeInsets.symmetric(vertical: _kEdgePadding),
width: isInAccessibilityMode
? _kAccessibilityCupertinoDialogWidth
: _kCupertinoDialogWidth,
child: CupertinoPopupSurface(
isSurfacePainted: false,
child: Semantics(
namesRoute: true,
scopesRoute: true,
explicitChildNodes: true,
label: localizations.alertDialogLabel,
child: _CupertinoDialogRenderWidget(
contentSection: _buildContent(context),
actionsSection: _buildActions(),
),
),
),
),
),
......
......@@ -65,16 +65,20 @@ class Dialog extends StatelessWidget {
/// {@macro flutter.material.material.elevation}
final double elevation;
/// {@template flutter.material.dialog.insetAnimationDuration}
/// The duration of the animation to show when the system keyboard intrudes
/// into the space that the dialog is placed in.
///
/// Defaults to 100 milliseconds.
/// {@endtemplate}
final Duration insetAnimationDuration;
/// {@template flutter.material.dialog.insetAnimationCurve}
/// The curve to use for the animation shown when the system keyboard intrudes
/// into the space that the dialog is placed in.
///
/// Defaults to [Curves.decelerate].
/// {@endtemplate}
final Curve insetAnimationCurve;
/// {@template flutter.material.dialog.shape}
......
......@@ -251,7 +251,7 @@ void main() {
tester.getSize(
find.byType(ClipRRect)
),
equals(const Size(310.0, 560.0)),
equals(const Size(310.0, 560.0 - 24.0 * 2)),
);
// Check sizes/locations of the text. The text is large so these 2 buttons are stacked.
......@@ -259,7 +259,7 @@ void main() {
// regular font. However, when using the test font, "Cancel" becomes 2 lines which
// is why the height we're verifying for "Cancel" is larger than "OK".
expect(tester.getSize(find.text('The Title')), equals(const Size(270.0, 162.0)));
expect(tester.getTopLeft(find.text('The Title')), equals(const Offset(265.0, 80.0)));
expect(tester.getTopLeft(find.text('The Title')), equals(const Offset(265.0, 80.0 + 24.0)));
expect(tester.getSize(find.widgetWithText(CupertinoDialogAction, 'Cancel')), equals(const Size(310.0, 148.0)));
expect(tester.getSize(find.widgetWithText(CupertinoDialogAction, 'OK')), equals(const Size(310.0, 98.0)));
});
......@@ -300,10 +300,12 @@ void main() {
await tester.pump();
const double topAndBottomMargin = 40.0;
const double topAndBottomPadding = 24.0 * 2;
const double leftAndRightPadding = 40.0 * 2;
final Finder modalFinder = find.byType(ClipRRect);
expect(
tester.getSize(modalFinder),
equals(const Size(200.0, 100.0 - topAndBottomMargin)),
equals(const Size(200.0 - leftAndRightPadding, 100.0 - topAndBottomMargin - topAndBottomPadding)),
);
});
......@@ -645,7 +647,7 @@ void main() {
// should be in a scrollable area equal to half the dialog height.
expect(
actionsSectionBox.size.height,
280.0,
280.0 - 24.0,
);
});
......@@ -1053,6 +1055,36 @@ void main() {
expect(find.byKey(const Key('option_2')), findsOneWidget);
expect(find.byKey(const Key('option_3')), findsNothing);
});
testWidgets('Dialog widget insets by MediaQuery viewInsets', (WidgetTester tester) async {
await tester.pumpWidget(
const MaterialApp(
home: MediaQuery(
data: MediaQueryData(viewInsets: EdgeInsets.zero),
child: CupertinoAlertDialog(content: Placeholder(fallbackHeight: 200.0)),
),
),
);
final Rect placeholderRectWithoutInsets = tester.getRect(find.byType(Placeholder));
await tester.pumpWidget(
const MaterialApp(
home: MediaQuery(
data: MediaQueryData(viewInsets: EdgeInsets.fromLTRB(40.0, 30.0, 20.0, 10.0)),
child: CupertinoAlertDialog(content: Placeholder(fallbackHeight: 200.0)),
),
),
);
// no change yet because padding is animated
expect(tester.getRect(find.byType(Placeholder)), placeholderRectWithoutInsets);
await tester.pump(const Duration(seconds: 1));
// once animation settles the dialog is padded by the new viewInsets
expect(tester.getRect(find.byType(Placeholder)), placeholderRectWithoutInsets.translate(10, 10));
});
}
RenderBox findActionButtonRenderBoxByTitle(WidgetTester tester, String title) {
......
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