Commit 79c797a1 authored by Adam Barth's avatar Adam Barth

AnimatedContainer has an issue with one config value change and not another

If we're already at the target value, we fail to configure the variable. If
another variable animates, we re-animate the other variable.

Fixes #958
parent 8694fada
......@@ -146,6 +146,14 @@ class _AnimatedContainerState extends State<AnimatedContainer> {
_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<AnimatedContainer> {
});
}
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<double>(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<double>(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) {
......
......@@ -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));
});
});
}
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