Skip to content

Commit 4aecec7

Browse files
authored
Expose foreground property of TextStyle in Icon widget (flutter#150315)
Expose foreground property to icon. See issues: - flutter#139411
1 parent d8ae99a commit 4aecec7

File tree

2 files changed

+41
-6
lines changed

2 files changed

+41
-6
lines changed

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

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -86,9 +86,10 @@ class Icon extends StatelessWidget {
8686
this.semanticLabel,
8787
this.textDirection,
8888
this.applyTextScaling,
89-
}) : assert(fill == null || (0.0 <= fill && fill <= 1.0)),
90-
assert(weight == null || (0.0 < weight)),
91-
assert(opticalSize == null || (0.0 < opticalSize));
89+
this.blendMode,
90+
}) : assert(fill == null || (0.0 <= fill && fill <= 1.0)),
91+
assert(weight == null || (0.0 < weight)),
92+
assert(opticalSize == null || (0.0 < opticalSize));
9293

9394
/// The icon to display. The available icons are described in [Icons].
9495
///
@@ -247,6 +248,11 @@ class Icon extends StatelessWidget {
247248
/// [IconThemeData.applyTextScaling].
248249
final bool? applyTextScaling;
249250

251+
/// The [BlendMode] to apply to the foreground of the icon.
252+
///
253+
/// Defaults to [BlendMode.srcOver]
254+
final BlendMode? blendMode;
255+
250256
@override
251257
Widget build(BuildContext context) {
252258
assert(this.textDirection != null || debugCheckHasDirectionality(context));
@@ -279,10 +285,18 @@ class Icon extends StatelessWidget {
279285
}
280286

281287
final double iconOpacity = iconTheme.opacity ?? 1.0;
282-
Color iconColor = color ?? iconTheme.color!;
288+
Color? iconColor = color ?? iconTheme.color!;
289+
Paint? foreground;
283290
if (iconOpacity != 1.0) {
284291
iconColor = iconColor.withOpacity(iconColor.opacity * iconOpacity);
285292
}
293+
if (blendMode != null) {
294+
foreground = Paint()
295+
..blendMode = blendMode!
296+
..color = iconColor;
297+
// Cannot provide both a color and a foreground.
298+
iconColor = null;
299+
}
286300

287301
final TextStyle fontStyle = TextStyle(
288302
fontVariations: <FontVariation>[
@@ -298,8 +312,9 @@ class Icon extends StatelessWidget {
298312
package: icon.fontPackage,
299313
fontFamilyFallback: icon.fontFamilyFallback,
300314
shadows: iconShadows,
301-
height: 1.0, // Makes sure the font's body is vertically centered within the iconSize x iconSize square.
315+
height: 1.0, // Makes sure the font's body is vertically centered within the iconSize x iconSize square.
302316
leadingDistribution: TextLeadingDistribution.even,
317+
foreground: foreground,
303318
);
304319

305320
Widget iconWidget = RichText(

packages/flutter/test/widgets/icon_test.dart

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -358,7 +358,6 @@ void main() {
358358
expect(const IconData(123).toString(), 'IconData(U+0007B)');
359359
});
360360

361-
362361
testWidgets('Fill, weight, grade, and optical size variations are passed', (WidgetTester tester) async {
363362
await tester.pumpWidget(
364363
const Directionality(
@@ -443,6 +442,27 @@ void main() {
443442
]);
444443
});
445444

445+
testWidgets("TextStyle's blendMode should bind in foreground property", (WidgetTester tester) async {
446+
await tester.pumpWidget(
447+
const Directionality(
448+
textDirection: TextDirection.ltr,
449+
child: Center(
450+
child: IconTheme(
451+
data: IconThemeData(opacity: 0.5),
452+
child: Icon(
453+
IconData(0x41),
454+
blendMode: BlendMode.clear,
455+
),
456+
),
457+
),
458+
),
459+
);
460+
461+
final RichText richText = tester.firstWidget(find.byType(RichText));
462+
expect(richText.text.style?.color, isNull);
463+
expect(richText.text.style?.foreground?.blendMode, BlendMode.clear);
464+
});
465+
446466
test('Throws if given invalid values', () {
447467
expect(() => Icon(Icons.abc, fill: -0.1), throwsAssertionError);
448468
expect(() => Icon(Icons.abc, fill: 1.1), throwsAssertionError);

0 commit comments

Comments
 (0)