Skip to content

Commit 238d79a

Browse files
Added useOriginalColors flag which allows ImageIcon to bypass IconTheme colorization and use the original colors (#180491)
<!-- Thanks for filing a pull request! Reviewers are typically assigned within a week of filing a request. To learn more about code review, see our documentation on Tree Hygiene: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md --> Added useOriginalColors flag which allows ImageIcon to bypass IconTheme colorization and use the original colors. Issue #180463 ## Pre-launch Checklist - [x] I read the [Contributor Guide] and followed the process outlined there for submitting PRs. - [x] I read the [Tree Hygiene] wiki page, which explains my responsibilities. - [x] I read and followed the [Flutter Style Guide], including [Features we expect every widget to implement]. - [x] I signed the [CLA]. - [x] I listed at least one issue that this PR fixes in the description above. - [x] I updated/added relevant documentation (doc comments with `///`). - [x] I added new tests to check the change I am making, or this PR is [test-exempt]. - [x] I followed the [breaking change policy] and added [Data Driven Fixes] where supported. - [x] All existing and new tests are passing. <!-- Links --> [Contributor Guide]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#overview [Tree Hygiene]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md [test-exempt]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#tests [Flutter Style Guide]: https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md [Features we expect every widget to implement]: https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md#features-we-expect-every-widget-to-implement [CLA]: https://cla.developers.google.com/ [flutter/tests]: https://github.com/flutter/tests [breaking change policy]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#handling-breaking-changes [Discord]: https://github.com/flutter/flutter/blob/main/docs/contributing/Chat.md [Data Driven Fixes]: https://github.com/flutter/flutter/blob/main/docs/contributing/Data-driven-Fixes.md --------- Co-authored-by: Victor Sanni <victorsanniay@gmail.com>
1 parent 47c0c90 commit 238d79a

2 files changed

Lines changed: 72 additions & 2 deletions

File tree

packages/flutter/lib/src/widgets/image_icon.dart

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,18 @@ class ImageIcon extends StatelessWidget {
2626
/// Creates an image icon.
2727
///
2828
/// The [size] and [color] default to the value given by the current [IconTheme].
29-
const ImageIcon(this.image, {super.key, this.size, this.color, this.semanticLabel});
29+
const ImageIcon(
30+
this.image, {
31+
super.key,
32+
this.size,
33+
this.color,
34+
this.semanticLabel,
35+
this.useOriginalColors = false,
36+
}) : assert(
37+
!(useOriginalColors && color != null),
38+
'Cannot provide a color while useOriginalColors is true. '
39+
'To use a specific color, set useOriginalColors to false or omit it.',
40+
);
3041

3142
/// The image to display as the icon.
3243
///
@@ -61,6 +72,21 @@ class ImageIcon extends StatelessWidget {
6172
/// underlying [Semantics] widget.
6273
final String? semanticLabel;
6374

75+
/// Whether to render the image using its original colors.
76+
///
77+
/// If this is false (the default), the image is colorized by merging the
78+
/// [color] (or, if that is null, the [IconTheme] color) with the image
79+
/// using [BlendMode.srcIn]. This is the standard behavior for icons.
80+
///
81+
/// If this is true, the color-blend filter is disabled, and the image is
82+
/// rendered with its original colors. This allows multi-colored images,
83+
/// such as brand logos, to be displayed accurately.
84+
///
85+
/// If this is true, [color] must be null.
86+
///
87+
/// Defaults to false.
88+
final bool useOriginalColors;
89+
6490
@override
6591
Widget build(BuildContext context) {
6692
final IconThemeData iconTheme = IconTheme.of(context);
@@ -86,7 +112,7 @@ class ImageIcon extends StatelessWidget {
86112
image: image!,
87113
width: iconSize,
88114
height: iconSize,
89-
color: iconColor,
115+
color: useOriginalColors ? null : iconColor,
90116
fit: BoxFit.scaleDown,
91117
excludeFromSemantics: true,
92118
),

packages/flutter/test/widgets/image_icon_test.dart

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,50 @@ void main() {
9898
handle.dispose();
9999
});
100100

101+
testWidgets('ImageIcon respects IconTheme color by default', (WidgetTester tester) async {
102+
await tester.pumpWidget(
103+
Directionality(
104+
textDirection: TextDirection.ltr,
105+
child: IconTheme(
106+
data: const IconThemeData(color: Color(0xFF0000FF)),
107+
child: ImageIcon(image),
108+
),
109+
),
110+
);
111+
112+
expect(tester.widget<Image>(find.byType(Image)).color, const Color(0xFF0000FF));
113+
imageCache.clear();
114+
});
115+
116+
testWidgets('ImageIcon ignores IconTheme color when useOriginalColors is true', (
117+
WidgetTester tester,
118+
) async {
119+
await tester.pumpWidget(
120+
Directionality(
121+
textDirection: TextDirection.ltr,
122+
child: IconTheme(
123+
data: const IconThemeData(color: Color(0xFF0000FF)),
124+
child: ImageIcon(image, useOriginalColors: true),
125+
),
126+
),
127+
);
128+
129+
expect(tester.widget<Image>(find.byType(Image)).color, null);
130+
imageCache.clear();
131+
});
132+
133+
testWidgets(
134+
'ImageIcon throws assertion error if color is provided and useOriginalColors is true',
135+
(WidgetTester tester) async {
136+
expect(
137+
() => ImageIcon(image, color: const Color(0xFF0000FF), useOriginalColors: true),
138+
throwsAssertionError,
139+
);
140+
141+
imageCache.clear();
142+
},
143+
);
144+
101145
testWidgets('ImageIcon does not crash at zero area', (WidgetTester tester) async {
102146
await tester.pumpWidget(
103147
Directionality(

0 commit comments

Comments
 (0)