From 50ead38f2f35b0ec166ebeedff119cd68f5ac95b Mon Sep 17 00:00:00 2001 From: Tuyen VU Date: Thu, 28 Oct 2021 05:18:03 +0700 Subject: [PATCH] - add FadeInImage.placeholderFit (#90739) --- .../lib/src/widgets/fade_in_image.dart | 16 +++++++++- .../test/widgets/fade_in_image_test.dart | 32 +++++++++++++++++++ 2 files changed, 47 insertions(+), 1 deletion(-) diff --git a/packages/flutter/lib/src/widgets/fade_in_image.dart b/packages/flutter/lib/src/widgets/fade_in_image.dart index d490ee26979..83255544191 100644 --- a/packages/flutter/lib/src/widgets/fade_in_image.dart +++ b/packages/flutter/lib/src/widgets/fade_in_image.dart @@ -67,6 +67,9 @@ class FadeInImage extends StatefulWidget { /// The [placeholder] and [image] may be composed in a [ResizeImage] to provide /// a custom decode/cache size. /// + /// The [placeholder] and [image] may be have their own BoxFit settings via [fit] + /// and [placeholderFit]. + /// /// The [placeholder], [image], [fadeOutDuration], [fadeOutCurve], /// [fadeInDuration], [fadeInCurve], [alignment], [repeat], and /// [matchTextDirection] arguments must not be null. @@ -87,6 +90,7 @@ class FadeInImage extends StatefulWidget { this.width, this.height, this.fit, + this.placeholderFit, this.alignment = Alignment.center, this.repeat = ImageRepeat.noRepeat, this.matchTextDirection = false, @@ -146,6 +150,7 @@ class FadeInImage extends StatefulWidget { this.width, this.height, this.fit, + this.placeholderFit, this.alignment = Alignment.center, this.repeat = ImageRepeat.noRepeat, this.matchTextDirection = false, @@ -217,6 +222,7 @@ class FadeInImage extends StatefulWidget { this.width, this.height, this.fit, + this.placeholderFit, this.alignment = Alignment.center, this.repeat = ImageRepeat.noRepeat, this.matchTextDirection = false, @@ -295,6 +301,11 @@ class FadeInImage extends StatefulWidget { /// [paintImage]. final BoxFit? fit; + /// How to inscribe the placeholder image into the space allocated during layout. + /// + /// If not value set, it will fallback to [fit]. + final BoxFit? placeholderFit; + /// How to align the image within its bounds. /// /// The alignment aligns the given position in the image to the given position @@ -376,6 +387,7 @@ class _FadeInImageState extends State { required ImageProvider image, ImageErrorWidgetBuilder? errorBuilder, ImageFrameBuilder? frameBuilder, + BoxFit? fit, required Animation opacity, }) { assert(image != null); @@ -386,7 +398,7 @@ class _FadeInImageState extends State { opacity: opacity, width: widget.width, height: widget.height, - fit: widget.fit, + fit: fit, alignment: widget.alignment, repeat: widget.repeat, matchTextDirection: widget.matchTextDirection, @@ -401,6 +413,7 @@ class _FadeInImageState extends State { image: widget.image, errorBuilder: widget.imageErrorBuilder, opacity: _imageAnimation, + fit: widget.fit, frameBuilder: (BuildContext context, Widget child, int? frame, bool wasSynchronouslyLoaded) { if (wasSynchronouslyLoaded) { _resetAnimations(); @@ -413,6 +426,7 @@ class _FadeInImageState extends State { image: widget.placeholder, errorBuilder: widget.placeholderErrorBuilder, opacity: _placeholderAnimation, + fit: widget.placeholderFit ?? widget.fit, ), placeholderProxyAnimation: _placeholderAnimation, isTargetLoaded: frame != null, diff --git a/packages/flutter/test/widgets/fade_in_image_test.dart b/packages/flutter/test/widgets/fade_in_image_test.dart index 65daffe4840..fea4302f6c4 100644 --- a/packages/flutter/test/widgets/fade_in_image_test.dart +++ b/packages/flutter/test/widgets/fade_in_image_test.dart @@ -49,6 +49,7 @@ class FadeInImageElements { RawImage get rawImage => rawImageElement.widget as RawImage; double get opacity => rawImage.opacity?.value ?? 1.0; + BoxFit? get fit => rawImage.fit; } class LoadTestImageProvider extends ImageProvider { @@ -435,5 +436,36 @@ Future main() async { }); }); }); + + group("placeholder's BoxFit", () { + testWidgets("should be the image's BoxFit when not set", (WidgetTester tester) async { + final TestImageProvider placeholderProvider = TestImageProvider(placeholderImage); + final TestImageProvider imageProvider = TestImageProvider(targetImage); + + await tester.pumpWidget(FadeInImage( + placeholder: placeholderProvider, + image: imageProvider, + fit: BoxFit.cover, + )); + + expect(findFadeInImage(tester).placeholder!.fit, equals(findFadeInImage(tester).target.fit)); + expect(findFadeInImage(tester).placeholder!.fit, equals(BoxFit.cover)); + }); + + testWidgets('should be the given value when set', (WidgetTester tester) async { + final TestImageProvider placeholderProvider = TestImageProvider(placeholderImage); + final TestImageProvider imageProvider = TestImageProvider(targetImage); + + await tester.pumpWidget(FadeInImage( + placeholder: placeholderProvider, + image: imageProvider, + fit: BoxFit.cover, + placeholderFit: BoxFit.fill, + )); + + expect(findFadeInImage(tester).target.fit, equals(BoxFit.cover)); + expect(findFadeInImage(tester).placeholder!.fit, equals(BoxFit.fill)); + }); + }); }); }