Unverified Commit 8aa67610 authored by Dan Field's avatar Dan Field Committed by GitHub

Avoid including a potentially animated invisible image (#50842)

* Avoid including a potentially animated invisible image
parent e4fbb1ab
......@@ -448,7 +448,13 @@ class _AnimatedFadeOutFadeInState extends ImplicitlyAnimatedWidgetState<_Animate
tween: ConstantTween<double>(0),
weight: widget.fadeInDuration.inMilliseconds.toDouble(),
),
]));
]))..addStatusListener((AnimationStatus status) {
if (_placeholderOpacityAnimation.isCompleted) {
// Need to rebuild to remove placeholder now that it is invisibile.
setState(() {});
}
});
_targetOpacityAnimation = animation.drive(TweenSequence<double>(<TweenSequenceItem<double>>[
TweenSequenceItem<double>(
tween: ConstantTween<double>(0),
......@@ -472,6 +478,15 @@ class _AnimatedFadeOutFadeInState extends ImplicitlyAnimatedWidgetState<_Animate
@override
Widget build(BuildContext context) {
final Widget target = FadeTransition(
opacity: _targetOpacityAnimation,
child: widget.target,
);
if (_placeholderOpacityAnimation.isCompleted) {
return target;
}
return Stack(
fit: StackFit.passthrough,
alignment: AlignmentDirectional.center,
......@@ -479,10 +494,7 @@ class _AnimatedFadeOutFadeInState extends ImplicitlyAnimatedWidgetState<_Animate
// but it allows the Stack to avoid a call to Directionality.of()
textDirection: TextDirection.ltr,
children: <Widget>[
FadeTransition(
opacity: _targetOpacityAnimation,
child: widget.target,
),
target,
FadeTransition(
opacity: _placeholderOpacityAnimation,
child: widget.placeholder,
......
......@@ -209,6 +209,28 @@ Future<void> main() async {
expect(findFadeInImage(tester).state, same(state));
});
testWidgets('does not keep the placeholder in the tree if it is invisible', (WidgetTester tester) async {
final TestImageProvider placeholderProvider = TestImageProvider(placeholderImage);
final TestImageProvider imageProvider = TestImageProvider(targetImage);
await tester.pumpWidget(FadeInImage(
placeholder: placeholderProvider,
image: imageProvider,
fadeOutDuration: animationDuration,
fadeInDuration: animationDuration,
excludeFromSemantics: true,
));
placeholderProvider.complete();
await tester.pumpAndSettle();
expect(find.byType(Image), findsNWidgets(2));
imageProvider.complete();
await tester.pumpAndSettle();
expect(find.byType(Image), findsOneWidget);
});
testWidgets('re-fades in the image when the target image is updated', (WidgetTester tester) async {
final TestImageProvider placeholderProvider = TestImageProvider(placeholderImage);
final TestImageProvider imageProvider = TestImageProvider(targetImage);
......@@ -285,7 +307,7 @@ Future<void> main() async {
expect(findFadeInImage(tester).target.opacity, moreOrLessEquals(1));
});
group(ImageProvider, () {
group('ImageProvider', () {
testWidgets('memory placeholder cacheWidth and cacheHeight is passed through', (WidgetTester tester) async {
final Uint8List testBytes = Uint8List.fromList(kTransparentImage);
......
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