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 ...@@ -448,7 +448,13 @@ class _AnimatedFadeOutFadeInState extends ImplicitlyAnimatedWidgetState<_Animate
tween: ConstantTween<double>(0), tween: ConstantTween<double>(0),
weight: widget.fadeInDuration.inMilliseconds.toDouble(), 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>>[ _targetOpacityAnimation = animation.drive(TweenSequence<double>(<TweenSequenceItem<double>>[
TweenSequenceItem<double>( TweenSequenceItem<double>(
tween: ConstantTween<double>(0), tween: ConstantTween<double>(0),
...@@ -472,6 +478,15 @@ class _AnimatedFadeOutFadeInState extends ImplicitlyAnimatedWidgetState<_Animate ...@@ -472,6 +478,15 @@ class _AnimatedFadeOutFadeInState extends ImplicitlyAnimatedWidgetState<_Animate
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final Widget target = FadeTransition(
opacity: _targetOpacityAnimation,
child: widget.target,
);
if (_placeholderOpacityAnimation.isCompleted) {
return target;
}
return Stack( return Stack(
fit: StackFit.passthrough, fit: StackFit.passthrough,
alignment: AlignmentDirectional.center, alignment: AlignmentDirectional.center,
...@@ -479,10 +494,7 @@ class _AnimatedFadeOutFadeInState extends ImplicitlyAnimatedWidgetState<_Animate ...@@ -479,10 +494,7 @@ class _AnimatedFadeOutFadeInState extends ImplicitlyAnimatedWidgetState<_Animate
// but it allows the Stack to avoid a call to Directionality.of() // but it allows the Stack to avoid a call to Directionality.of()
textDirection: TextDirection.ltr, textDirection: TextDirection.ltr,
children: <Widget>[ children: <Widget>[
FadeTransition( target,
opacity: _targetOpacityAnimation,
child: widget.target,
),
FadeTransition( FadeTransition(
opacity: _placeholderOpacityAnimation, opacity: _placeholderOpacityAnimation,
child: widget.placeholder, child: widget.placeholder,
......
...@@ -209,6 +209,28 @@ Future<void> main() async { ...@@ -209,6 +209,28 @@ Future<void> main() async {
expect(findFadeInImage(tester).state, same(state)); 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 { testWidgets('re-fades in the image when the target image is updated', (WidgetTester tester) async {
final TestImageProvider placeholderProvider = TestImageProvider(placeholderImage); final TestImageProvider placeholderProvider = TestImageProvider(placeholderImage);
final TestImageProvider imageProvider = TestImageProvider(targetImage); final TestImageProvider imageProvider = TestImageProvider(targetImage);
...@@ -285,7 +307,7 @@ Future<void> main() async { ...@@ -285,7 +307,7 @@ Future<void> main() async {
expect(findFadeInImage(tester).target.opacity, moreOrLessEquals(1)); expect(findFadeInImage(tester).target.opacity, moreOrLessEquals(1));
}); });
group(ImageProvider, () { group('ImageProvider', () {
testWidgets('memory placeholder cacheWidth and cacheHeight is passed through', (WidgetTester tester) async { testWidgets('memory placeholder cacheWidth and cacheHeight is passed through', (WidgetTester tester) async {
final Uint8List testBytes = Uint8List.fromList(kTransparentImage); 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