From 42d4f6956682e03894523ca3cdc259df5800eefb Mon Sep 17 00:00:00 2001 From: Ujjwal Pratap Singh <85453780+ujjwaltwitx@users.noreply.github.com> Date: Wed, 19 Mar 2025 11:10:18 +0530 Subject: [PATCH] fix: "show dialog" functions should allow setting an AnimationStyle (#164002) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit fixes issue #154744 ## Pre-launch Checklist - [✅] I read the [Contributor Guide] and followed the process outlined there for submitting PRs. - [✅] I read the [Tree Hygiene] wiki page, which explains my responsibilities. - [✅] I read and followed the [Flutter Style Guide], including [Features we expect every widget to implement]. - [✅] I signed the [CLA]. - [✅] I listed at least one issue that this PR fixes in the description above. - [✅] I updated/added relevant documentation (doc comments with `///`). - [✅] I added new tests to check the change I am making, or this PR is [test-exempt]. - [✅] I followed the [breaking change policy] and added [Data Driven Fixes] where supported. - [✅] All existing and new tests are passing. If you need help, consider asking for advice on the #hackers-new channel on [Discord]. [Contributor Guide]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#overview [Tree Hygiene]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md [test-exempt]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#tests [Flutter Style Guide]: https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md [Features we expect every widget to implement]: https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md#features-we-expect-every-widget-to-implement [CLA]: https://cla.developers.google.com/ [flutter/tests]: https://github.com/flutter/tests [breaking change policy]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#handling-breaking-changes [Discord]: https://github.com/flutter/flutter/blob/main/docs/contributing/Chat.md [Data Driven Fixes]: https://github.com/flutter/flutter/blob/main/docs/contributing/Data-driven-Fixes.md --------- Co-authored-by: Tong Mu --- packages/flutter/lib/src/material/dialog.dart | 17 ++++++++-- .../flutter/test/material/dialog_test.dart | 33 +++++++++++++++++++ 2 files changed, 47 insertions(+), 3 deletions(-) diff --git a/packages/flutter/lib/src/material/dialog.dart b/packages/flutter/lib/src/material/dialog.dart index 0a36900c0e1..cd17f761cf8 100644 --- a/packages/flutter/lib/src/material/dialog.dart +++ b/packages/flutter/lib/src/material/dialog.dart @@ -1466,6 +1466,7 @@ Future showDialog({ Offset? anchorPoint, TraversalEdgeBehavior? traversalEdgeBehavior, bool? requestFocus, + AnimationStyle? animationStyle, }) { assert(_debugIsActive(context)); assert(debugCheckHasMaterialLocalizations(context)); @@ -1492,6 +1493,7 @@ Future showDialog({ anchorPoint: anchorPoint, traversalEdgeBehavior: traversalEdgeBehavior ?? TraversalEdgeBehavior.closedLoop, requestFocus: requestFocus, + animationStyle: animationStyle, ), ); } @@ -1516,6 +1518,7 @@ Future showAdaptiveDialog({ Offset? anchorPoint, TraversalEdgeBehavior? traversalEdgeBehavior, bool? requestFocus, + AnimationStyle? animationStyle, }) { final ThemeData theme = Theme.of(context); switch (theme.platform) { @@ -1535,6 +1538,7 @@ Future showAdaptiveDialog({ anchorPoint: anchorPoint, traversalEdgeBehavior: traversalEdgeBehavior, requestFocus: requestFocus, + animationStyle: animationStyle, ); case TargetPlatform.iOS: case TargetPlatform.macOS: @@ -1628,7 +1632,9 @@ class DialogRoute extends RawDialogRoute { super.requestFocus, super.anchorPoint, super.traversalEdgeBehavior, - }) : super( + AnimationStyle? animationStyle, + }) : _animationStyle = animationStyle, + super( pageBuilder: ( BuildContext buildContext, Animation animation, @@ -1642,16 +1648,21 @@ class DialogRoute extends RawDialogRoute { return dialog; }, barrierLabel: barrierLabel ?? MaterialLocalizations.of(context).modalBarrierDismissLabel, - transitionDuration: const Duration(milliseconds: 150), + transitionDuration: animationStyle?.duration ?? const Duration(milliseconds: 150), transitionBuilder: _buildMaterialDialogTransitions, ); CurvedAnimation? _curvedAnimation; + final AnimationStyle? _animationStyle; void _setAnimation(Animation animation) { if (_curvedAnimation?.parent != animation) { _curvedAnimation?.dispose(); - _curvedAnimation = CurvedAnimation(parent: animation, curve: Curves.easeOut); + _curvedAnimation = CurvedAnimation( + parent: animation, + curve: _animationStyle?.curve ?? Curves.easeOut, + reverseCurve: _animationStyle?.reverseCurve ?? Curves.easeOut, + ); } } diff --git a/packages/flutter/test/material/dialog_test.dart b/packages/flutter/test/material/dialog_test.dart index f01c488b7cc..f54ddda37ee 100644 --- a/packages/flutter/test/material/dialog_test.dart +++ b/packages/flutter/test/material/dialog_test.dart @@ -2682,6 +2682,39 @@ void main() { expect(find.text('Dialog2'), findsOneWidget); }); + testWidgets('Applies AnimationStyle to showAdaptiveDialog', (WidgetTester tester) async { + const AnimationStyle animationStyle = AnimationStyle( + duration: Duration(seconds: 1), + curve: Curves.easeInOut, + ); + + await tester.pumpWidget( + const MaterialApp( + home: Material(child: Center(child: ElevatedButton(onPressed: null, child: Text('Go')))), + ), + ); + final BuildContext context = tester.element(find.text('Go')); + showAdaptiveDialog( + context: context, + builder: (BuildContext context) { + return Container( + width: 100.0, + height: 100.0, + alignment: Alignment.center, + child: const Text('Dialog1'), + ); + }, + animationStyle: animationStyle, + ); + + await tester.pumpAndSettle(const Duration(seconds: 1)); + expect(find.text('Dialog1'), findsOneWidget); + + await tester.tapAt(const Offset(10.0, 10.0)); + await tester.pumpAndSettle(const Duration(seconds: 1)); + expect(find.text('Dialog1'), findsNothing); + }); + testWidgets('Uses open focus traversal when overridden', (WidgetTester tester) async { final FocusNode okNode = FocusNode(); addTearDown(okNode.dispose);