From e24cdab517faacc499c13545219e6acef357e99b Mon Sep 17 00:00:00 2001 From: Neevash Ramdial Date: Wed, 15 Jul 2020 12:46:03 -0400 Subject: [PATCH] Re-land Expose height and width factor in AnimatedAlign (#61136) --- .../lib/src/widgets/implicit_animations.dart | 26 +++++ packages/flutter/test/widgets/align_test.dart | 47 ++++++++ .../test/widgets/animated_align_test.dart | 100 ++++++++++++++++++ 3 files changed, 173 insertions(+) diff --git a/packages/flutter/lib/src/widgets/implicit_animations.dart b/packages/flutter/lib/src/widgets/implicit_animations.dart index b8a01fb6888..75b8246a4c4 100644 --- a/packages/flutter/lib/src/widgets/implicit_animations.dart +++ b/packages/flutter/lib/src/widgets/implicit_animations.dart @@ -882,10 +882,14 @@ class AnimatedAlign extends ImplicitlyAnimatedWidget { Key key, @required this.alignment, this.child, + this.heightFactor, + this.widthFactor, Curve curve = Curves.linear, @required Duration duration, VoidCallback onEnd, }) : assert(alignment != null), + assert(widthFactor == null || widthFactor >= 0.0), + assert(heightFactor == null || heightFactor >= 0.0), super(key: key, curve: curve, duration: duration, onEnd: onEnd); /// How to align the child. @@ -911,6 +915,16 @@ class AnimatedAlign extends ImplicitlyAnimatedWidget { /// {@macro flutter.widgets.child} final Widget child; + /// If non-null, sets its height to the child's height multiplied by this factor. + /// + /// Must be greater than or equal to 0.0, defaults to null. + final double heightFactor; + + /// If non-null, sets its width to the child's width multiplied by this factor. + /// + /// Must be greater than or equal to 0.0, defaults to null. + final double widthFactor; + @override _AnimatedAlignState createState() => _AnimatedAlignState(); @@ -923,16 +937,26 @@ class AnimatedAlign extends ImplicitlyAnimatedWidget { class _AnimatedAlignState extends AnimatedWidgetBaseState { AlignmentGeometryTween _alignment; + Tween _heightFactorTween; + Tween _widthFactorTween; @override void forEachTween(TweenVisitor visitor) { _alignment = visitor(_alignment, widget.alignment, (dynamic value) => AlignmentGeometryTween(begin: value as AlignmentGeometry)) as AlignmentGeometryTween; + if(widget.heightFactor != null) { + _heightFactorTween = visitor(_heightFactorTween, widget.heightFactor, (dynamic value) => Tween(begin: value as double)) as Tween; + } + if(widget.widthFactor != null) { + _widthFactorTween = visitor(_widthFactorTween, widget.widthFactor, (dynamic value) => Tween(begin: value as double)) as Tween; + } } @override Widget build(BuildContext context) { return Align( alignment: _alignment.evaluate(animation), + heightFactor: _heightFactorTween?.evaluate(animation), + widthFactor: _widthFactorTween?.evaluate(animation), child: widget.child, ); } @@ -941,6 +965,8 @@ class _AnimatedAlignState extends AnimatedWidgetBaseState { void debugFillProperties(DiagnosticPropertiesBuilder description) { super.debugFillProperties(description); description.add(DiagnosticsProperty('alignment', _alignment, defaultValue: null)); + description.add(DiagnosticsProperty>('widthFactor', _widthFactorTween, defaultValue: null)); + description.add(DiagnosticsProperty>('heightFactor', _heightFactorTween, defaultValue: null)); } } diff --git a/packages/flutter/test/widgets/align_test.dart b/packages/flutter/test/widgets/align_test.dart index b6d4e5c13a0..c164d2514b2 100644 --- a/packages/flutter/test/widgets/align_test.dart +++ b/packages/flutter/test/widgets/align_test.dart @@ -112,4 +112,51 @@ void main() { expect(size.width, equals(800.0)); expect(size.height, equals(10.0)); }); + + testWidgets('Align widthFactor', (WidgetTester tester) async { + await tester.pumpWidget( + Directionality( + textDirection: TextDirection.ltr, + child: Row( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Align( + widthFactor: 0.5, + child: Container( + height: 100.0, + width: 100.0, + ), + ), + ], + ), + ), + ); + final RenderBox box = tester.renderObject(find.byType(Align)); + expect(box.size.width, equals(50.0)); + }); + + testWidgets('Align heightFactor', (WidgetTester tester) async { + await tester.pumpWidget( + Directionality( + textDirection: TextDirection.ltr, + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Align( + alignment: Alignment.center, + heightFactor: 0.5, + child: Container( + height: 100.0, + width: 100.0, + ), + ), + ], + ), + ), + ); + final RenderBox box = tester.renderObject(find.byType(Align)); + expect(box.size.height, equals(50.0)); + }); } diff --git a/packages/flutter/test/widgets/animated_align_test.dart b/packages/flutter/test/widgets/animated_align_test.dart index 9f99d8035db..82e1b5a465a 100644 --- a/packages/flutter/test/widgets/animated_align_test.dart +++ b/packages/flutter/test/widgets/animated_align_test.dart @@ -59,4 +59,104 @@ void main() { expect(tester.getSize(find.byKey(target)), const Size(100.0, 200.0)); expect(tester.getTopRight(find.byKey(target)), const Offset(800.0, 400.0)); }); + + testWidgets('AnimatedAlign widthFactor', (WidgetTester tester) async { + await tester.pumpWidget( + Directionality( + textDirection: TextDirection.ltr, + child: Row( + mainAxisSize: MainAxisSize.min, + children: [ + AnimatedAlign( + alignment: Alignment.center, + curve: Curves.ease, + widthFactor: 0.5, + duration: const Duration(milliseconds: 200), + child: Container( + height: 100.0, + width: 100.0, + ), + ), + ], + ), + ), + ); + final RenderBox box = tester.renderObject(find.byType(AnimatedAlign)); + expect(box.size.width, equals(50.0)); + }); + + testWidgets('AnimatedAlign heightFactor', (WidgetTester tester) async { + await tester.pumpWidget( + Directionality( + textDirection: TextDirection.ltr, + child: Column( + children: [ + AnimatedAlign( + alignment: Alignment.center, + curve: Curves.ease, + heightFactor: 0.5, + duration: const Duration(milliseconds: 200), + child: Container( + height: 100.0, + width: 100.0, + ), + ), + ], + ), + ), + ); + final RenderBox box = tester.renderObject(find.byType(AnimatedAlign)); + expect(box.size.height, equals( 50.0)); + }); + + testWidgets('AnimatedAlign null height factor', (WidgetTester tester) async { + await tester.pumpWidget( + Directionality( + textDirection: TextDirection.ltr, + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + AnimatedAlign( + alignment: Alignment.center, + curve: Curves.ease, + duration: const Duration(milliseconds: 200), + child: Container( + height: 100.0, + width: 100.0, + ), + ), + ], + ), + ), + ); + final RenderBox box = tester.renderObject(find.byType(Container)); + expect(box.size, equals(const Size(100.0, 100))); + }); + + testWidgets('AnimatedAlign null widthFactor', (WidgetTester tester) async { + await tester.pumpWidget( + Directionality( + textDirection: TextDirection.ltr, + child: SizedBox.shrink( + child: Row( + mainAxisSize: MainAxisSize.min, + mainAxisAlignment: MainAxisAlignment.center, + children: [ + AnimatedAlign( + alignment: Alignment.center, + curve: Curves.ease, + duration: const Duration(milliseconds: 200), + child: Container( + height: 100.0, + width: 100.0, + ), + ), + ], + ), + ), + ), + ); + final RenderBox box = tester.renderObject(find.byType(Container)); + expect(box.size, equals(const Size(100.0, 100))); + }); }