diff --git a/packages/flutter/lib/src/widgets/animated_container.dart b/packages/flutter/lib/src/widgets/animated_container.dart index 31ab3d7c43..54bee6018e 100644 --- a/packages/flutter/lib/src/widgets/animated_container.dart +++ b/packages/flutter/lib/src/widgets/animated_container.dart @@ -146,6 +146,14 @@ class _AnimatedContainerState extends State { _updateCurve(); _performanceController.duration = config.duration; if (_configAllVariables()) { + _updateBeginValue(_constraints); + _updateBeginValue(_decoration); + _updateBeginValue(_foregroundDecoration); + _updateBeginValue(_margin); + _updateBeginValue(_padding); + _updateBeginValue(_transform); + _updateBeginValue(_width); + _updateBeginValue(_height); _performanceController.progress = 0.0; _performanceController.play(); } @@ -183,82 +191,84 @@ class _AnimatedContainerState extends State { }); } - bool _configVariable(AnimatedValue variable, dynamic targetValue) { + bool _updateEndValue(AnimatedValue variable, dynamic targetValue) { if (targetValue == variable.end) return false; - dynamic currentValue = variable.value; variable.end = targetValue; - variable.begin = currentValue; - return currentValue != targetValue; + return true; + } + + void _updateBeginValue(AnimatedValue variable) { + variable?.begin = variable.value; } bool _configAllVariables() { - bool needsAnimation = false; + bool startAnimation = false; if (config.constraints != null) { _constraints ??= new AnimatedBoxConstraintsValue(config.constraints); - if (_configVariable(_constraints, config.constraints)) - needsAnimation = true; + if (_updateEndValue(_constraints, config.constraints)) + startAnimation = true; } else { _constraints = null; } if (config.decoration != null) { _decoration ??= new AnimatedDecorationValue(config.decoration); - if (_configVariable(_decoration, config.decoration)) - needsAnimation = true; + if (_updateEndValue(_decoration, config.decoration)) + startAnimation = true; } else { _decoration = null; } if (config.foregroundDecoration != null) { _foregroundDecoration ??= new AnimatedDecorationValue(config.foregroundDecoration); - if (_configVariable(_foregroundDecoration, config.foregroundDecoration)) - needsAnimation = true; + if (_updateEndValue(_foregroundDecoration, config.foregroundDecoration)) + startAnimation = true; } else { _foregroundDecoration = null; } if (config.margin != null) { _margin ??= new AnimatedEdgeDimsValue(config.margin); - if (_configVariable(_margin, config.margin)) - needsAnimation = true; + if (_updateEndValue(_margin, config.margin)) + startAnimation = true; } else { _margin = null; } if (config.padding != null) { _padding ??= new AnimatedEdgeDimsValue(config.padding); - if (_configVariable(_padding, config.padding)) - needsAnimation = true; + if (_updateEndValue(_padding, config.padding)) + startAnimation = true; } else { _padding = null; } if (config.transform != null) { _transform ??= new AnimatedMatrix4Value(config.transform); - if (_configVariable(_transform, config.transform)) - needsAnimation = true; + if (_updateEndValue(_transform, config.transform)) + startAnimation = true; } else { _transform = null; } if (config.width != null) { _width ??= new AnimatedValue(config.width); - if (_configVariable(_width, config.width)) - needsAnimation = true; + if (_updateEndValue(_width, config.width)) + startAnimation = true; } else { _width = null; } if (config.height != null) { _height ??= new AnimatedValue(config.height); - if (_configVariable(_height, config.height)) - needsAnimation = true; + if (_updateEndValue(_height, config.height)) + startAnimation = true; } else { _height = null; } - return needsAnimation; + return startAnimation; } Widget build(BuildContext context) { diff --git a/packages/flutter/test/widget/animated_container_test.dart b/packages/flutter/test/widget/animated_container_test.dart index e317f11962..fac5763fea 100644 --- a/packages/flutter/test/widget/animated_container_test.dart +++ b/packages/flutter/test/widget/animated_container_test.dart @@ -100,4 +100,74 @@ void main() { expect(tester.binding.transientCallbackCount, 0); }); }); + + test('Animation rerun', () { + testWidgets((WidgetTester tester) { + tester.pumpWidget( + new Center( + child: new AnimatedContainer( + duration: const Duration(milliseconds: 200), + width: 100.0, + height: 100.0, + child: new Text('X') + ) + ) + ); + + tester.pump(); + tester.pump(new Duration(milliseconds: 100)); + + RenderBox text = tester.findText('X').renderObject; + expect(text.size.width, equals(100.0)); + expect(text.size.height, equals(100.0)); + + tester.pump(new Duration(milliseconds: 1000)); + + tester.pumpWidget( + new Center( + child: new AnimatedContainer( + duration: const Duration(milliseconds: 200), + width: 200.0, + height: 200.0, + child: new Text('X') + ) + ) + ); + tester.pump(); + tester.pump(new Duration(milliseconds: 100)); + + text = tester.findText('X').renderObject; + expect(text.size.width, greaterThan(110.0)); + expect(text.size.width, lessThan(190.0)); + expect(text.size.height, greaterThan(110.0)); + expect(text.size.height, lessThan(190.0)); + + tester.pump(new Duration(milliseconds: 1000)); + + expect(text.size.width, equals(200.0)); + expect(text.size.height, equals(200.0)); + + tester.pumpWidget( + new Center( + child: new AnimatedContainer( + duration: const Duration(milliseconds: 200), + width: 200.0, + height: 100.0, + child: new Text('X') + ) + ) + ); + tester.pump(); + tester.pump(new Duration(milliseconds: 100)); + + expect(text.size.width, equals(200.0)); + expect(text.size.height, greaterThan(110.0)); + expect(text.size.height, lessThan(190.0)); + + tester.pump(new Duration(milliseconds: 1000)); + + expect(text.size.width, equals(200.0)); + expect(text.size.height, equals(100.0)); + }); + }); }