Unverified Commit 7faa6261 authored by sanni prasad's avatar sanni prasad Committed by GitHub

Add support for color and color blendmode in FadeInImage (#137681)

Added "color" and "colorBlendMode" props in [FadeInImage](https://api.flutter.dev/flutter/widgets/FadeInImage-class.html) and applied it to both placeholder and the target image.

Added test to check weather both properties are applied to placeholder and the target image.

Fixes  https://github.com/flutter/flutter/issues/128229

Migration is not required because I have added two optional props and have not updated any existing code. Devs may choose to use them if they have a usecase. Existing projects should not get affected.(no errors or warning)
parent 4b4a1feb
......@@ -84,6 +84,10 @@ class FadeInImage extends StatefulWidget {
this.fadeOutCurve = Curves.easeOut,
this.fadeInDuration = const Duration(milliseconds: 700),
this.fadeInCurve = Curves.easeIn,
this.color,
this.colorBlendMode,
this.placeholderColor,
this.placeholderColorBlendMode,
this.width,
this.height,
this.fit,
......@@ -140,6 +144,10 @@ class FadeInImage extends StatefulWidget {
this.width,
this.height,
this.fit,
this.color,
this.colorBlendMode,
this.placeholderColor,
this.placeholderColorBlendMode,
this.placeholderFit,
this.filterQuality = FilterQuality.low,
this.placeholderFilterQuality,
......@@ -198,6 +206,10 @@ class FadeInImage extends StatefulWidget {
this.width,
this.height,
this.fit,
this.color,
this.colorBlendMode,
this.placeholderColor,
this.placeholderColorBlendMode,
this.placeholderFit,
this.filterQuality = FilterQuality.low,
this.placeholderFilterQuality,
......@@ -254,6 +266,46 @@ class FadeInImage extends StatefulWidget {
/// also affected by the scale factor.
final double? width;
/// If non-null, this color is blended with each image pixel using [colorBlendMode].
///
/// Color applies to the [image].
///
/// See Also:
///
/// * [placeholderColor], the color which applies to the [placeholder].
final Color? color;
/// Used to combine [color] with this [image].
///
/// The default is [BlendMode.srcIn]. In terms of the blend mode, [color] is
/// the source and this image is the destination.
///
/// See also:
///
/// * [BlendMode], which includes an illustration of the effect of each blend mode.
/// * [placeholderColorBlendMode], the color blend mode which applies to the [placeholder].
final BlendMode? colorBlendMode;
/// If non-null, this color is blended with each placeholder image pixel using [placeholderColorBlendMode].
///
/// Color applies to the [placeholder].
///
/// See Also:
///
/// * [color], the color which applies to the [image].
final Color? placeholderColor;
/// Used to combine [placeholderColor] with the [placeholder] image.
///
/// The default is [BlendMode.srcIn]. In terms of the blend mode, [placeholderColor] is
/// the source and this placeholder is the destination.
///
/// See also:
///
/// * [BlendMode], which includes an illustration of the effect of each blend mode.
/// * [colorBlendMode], the color blend mode which applies to the [image].
final BlendMode? placeholderColorBlendMode;
/// If non-null, require the image to have this height.
///
/// If null, the image will pick a size that best preserves its intrinsic
......@@ -361,6 +413,8 @@ class _FadeInImageState extends State<FadeInImage> {
ImageErrorWidgetBuilder? errorBuilder,
ImageFrameBuilder? frameBuilder,
BoxFit? fit,
Color? color,
BlendMode? colorBlendMode,
required FilterQuality filterQuality,
required Animation<double> opacity,
}) {
......@@ -372,6 +426,8 @@ class _FadeInImageState extends State<FadeInImage> {
width: widget.width,
height: widget.height,
fit: fit,
color: color,
colorBlendMode: colorBlendMode,
filterQuality: filterQuality,
alignment: widget.alignment,
repeat: widget.repeat,
......@@ -388,6 +444,8 @@ class _FadeInImageState extends State<FadeInImage> {
errorBuilder: widget.imageErrorBuilder,
opacity: _imageAnimation,
fit: widget.fit,
color: widget.color,
colorBlendMode: widget.colorBlendMode,
filterQuality: widget.filterQuality,
frameBuilder: (BuildContext context, Widget child, int? frame, bool wasSynchronouslyLoaded) {
if (wasSynchronouslyLoaded || frame != null) {
......@@ -400,6 +458,8 @@ class _FadeInImageState extends State<FadeInImage> {
image: widget.placeholder,
errorBuilder: widget.placeholderErrorBuilder,
opacity: _placeholderAnimation,
color: widget.placeholderColor,
colorBlendMode: widget.placeholderColorBlendMode,
fit: widget.placeholderFit ?? widget.fit,
filterQuality: widget.placeholderFilterQuality ?? widget.filterQuality,
),
......
......@@ -42,6 +42,8 @@ class FadeInImageElements {
double get opacity => rawImage.opacity?.value ?? 1.0;
BoxFit? get fit => rawImage.fit;
FilterQuality? get filterQuality => rawImage.filterQuality;
Color? get color => rawImage.color;
BlendMode? get colorBlendMode => rawImage.colorBlendMode;
}
class LoadTestImageProvider extends ImageProvider<Object> {
......@@ -378,6 +380,29 @@ void main() {
expect(findFadeInImage(tester).target.opacity, moreOrLessEquals(1));
});
testWidgetsWithLeakTracking('Image color and colorBlend parameters', (WidgetTester tester) async {
final TestImageProvider placeholderProvider = TestImageProvider(placeholderImage);
final TestImageProvider imageProvider = TestImageProvider(targetImage);
await tester.pumpWidget(FadeInImage(
placeholder: placeholderProvider,
image: imageProvider,
color: const Color(0xFF00FF00),
colorBlendMode: BlendMode.clear,
placeholderColor: const Color(0xFF0000FF),
placeholderColorBlendMode: BlendMode.modulate,
fadeOutDuration: animationDuration,
fadeInDuration: animationDuration,
excludeFromSemantics: true,
));
expect(findFadeInImage(tester).placeholder?.color, const Color(0xFF0000FF));
expect(findFadeInImage(tester).placeholder?.colorBlendMode, BlendMode.modulate);
await tester.pump(animationDuration);
expect(findFadeInImage(tester).target.color, const Color(0xFF00FF00));
expect(findFadeInImage(tester).target.colorBlendMode, BlendMode.clear);
});
group('ImageProvider', () {
test('memory placeholder cacheWidth and cacheHeight is passed through', () async {
......
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