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 { ...@@ -129,6 +129,8 @@ class CupertinoAlertDialog extends StatelessWidget {
this.actions = const <Widget>[], this.actions = const <Widget>[],
this.scrollController, this.scrollController,
this.actionScrollController, this.actionScrollController,
this.insetAnimationDuration = const Duration(milliseconds: 100),
this.insetAnimationCurve = Curves.decelerate,
}) : assert(actions != null), }) : assert(actions != null),
super(key: key); super(key: key);
...@@ -173,6 +175,12 @@ class CupertinoAlertDialog extends StatelessWidget { ...@@ -173,6 +175,12 @@ class CupertinoAlertDialog extends StatelessWidget {
/// section when it is long. /// section when it is long.
final ScrollController actionScrollController; final ScrollController actionScrollController;
/// {@macro flutter.material.dialog.insetAnimationDuration}
final Duration insetAnimationDuration;
/// {@macro flutter.material.dialog.insetAnimationCurve}
final Curve insetAnimationCurve;
Widget _buildContent(BuildContext context) { Widget _buildContent(BuildContext context) {
final List<Widget> children = <Widget>[ final List<Widget> children = <Widget>[
if (title != null || content != null) if (title != null || content != null)
...@@ -224,22 +232,35 @@ class CupertinoAlertDialog extends StatelessWidget { ...@@ -224,22 +232,35 @@ class CupertinoAlertDialog extends StatelessWidget {
), ),
child: LayoutBuilder( child: LayoutBuilder(
builder: (BuildContext context, BoxConstraints constraints) { builder: (BuildContext context, BoxConstraints constraints) {
return Center( return AnimatedPadding(
child: Container( padding: MediaQuery.of(context).viewInsets +
margin: const EdgeInsets.symmetric(vertical: _kEdgePadding), const EdgeInsets.symmetric(horizontal: 40.0, vertical: 24.0),
width: isInAccessibilityMode duration: insetAnimationDuration,
? _kAccessibilityCupertinoDialogWidth curve: insetAnimationCurve,
: _kCupertinoDialogWidth, child: MediaQuery.removeViewInsets(
child: CupertinoPopupSurface( removeLeft: true,
isSurfacePainted: false, removeTop: true,
child: Semantics( removeRight: true,
namesRoute: true, removeBottom: true,
scopesRoute: true, context: context,
explicitChildNodes: true, child: Center(
label: localizations.alertDialogLabel, child: Container(
child: _CupertinoDialogRenderWidget( margin: const EdgeInsets.symmetric(vertical: _kEdgePadding),
contentSection: _buildContent(context), width: isInAccessibilityMode
actionsSection: _buildActions(), ? _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 { ...@@ -65,16 +65,20 @@ class Dialog extends StatelessWidget {
/// {@macro flutter.material.material.elevation} /// {@macro flutter.material.material.elevation}
final double elevation; final double elevation;
/// {@template flutter.material.dialog.insetAnimationDuration}
/// The duration of the animation to show when the system keyboard intrudes /// The duration of the animation to show when the system keyboard intrudes
/// into the space that the dialog is placed in. /// into the space that the dialog is placed in.
/// ///
/// Defaults to 100 milliseconds. /// Defaults to 100 milliseconds.
/// {@endtemplate}
final Duration insetAnimationDuration; final Duration insetAnimationDuration;
/// {@template flutter.material.dialog.insetAnimationCurve}
/// The curve to use for the animation shown when the system keyboard intrudes /// The curve to use for the animation shown when the system keyboard intrudes
/// into the space that the dialog is placed in. /// into the space that the dialog is placed in.
/// ///
/// Defaults to [Curves.decelerate]. /// Defaults to [Curves.decelerate].
/// {@endtemplate}
final Curve insetAnimationCurve; final Curve insetAnimationCurve;
/// {@template flutter.material.dialog.shape} /// {@template flutter.material.dialog.shape}
......
...@@ -251,7 +251,7 @@ void main() { ...@@ -251,7 +251,7 @@ void main() {
tester.getSize( tester.getSize(
find.byType(ClipRRect) 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. // Check sizes/locations of the text. The text is large so these 2 buttons are stacked.
...@@ -259,7 +259,7 @@ void main() { ...@@ -259,7 +259,7 @@ void main() {
// regular font. However, when using the test font, "Cancel" becomes 2 lines which // 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". // 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.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, 'Cancel')), equals(const Size(310.0, 148.0)));
expect(tester.getSize(find.widgetWithText(CupertinoDialogAction, 'OK')), equals(const Size(310.0, 98.0))); expect(tester.getSize(find.widgetWithText(CupertinoDialogAction, 'OK')), equals(const Size(310.0, 98.0)));
}); });
...@@ -300,10 +300,12 @@ void main() { ...@@ -300,10 +300,12 @@ void main() {
await tester.pump(); await tester.pump();
const double topAndBottomMargin = 40.0; const double topAndBottomMargin = 40.0;
const double topAndBottomPadding = 24.0 * 2;
const double leftAndRightPadding = 40.0 * 2;
final Finder modalFinder = find.byType(ClipRRect); final Finder modalFinder = find.byType(ClipRRect);
expect( expect(
tester.getSize(modalFinder), 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() { ...@@ -645,7 +647,7 @@ void main() {
// should be in a scrollable area equal to half the dialog height. // should be in a scrollable area equal to half the dialog height.
expect( expect(
actionsSectionBox.size.height, actionsSectionBox.size.height,
280.0, 280.0 - 24.0,
); );
}); });
...@@ -1053,6 +1055,36 @@ void main() { ...@@ -1053,6 +1055,36 @@ void main() {
expect(find.byKey(const Key('option_2')), findsOneWidget); expect(find.byKey(const Key('option_2')), findsOneWidget);
expect(find.byKey(const Key('option_3')), findsNothing); 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) { 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