Pad CupertinoAlertDialog with MediaQuery viewInsets (#42967)
Fixes #42049.
This commit is contained in:
@@ -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) {
|
||||
|
||||
Reference in New Issue
Block a user