diff --git a/packages/flutter/lib/src/widgets/icon.dart b/packages/flutter/lib/src/widgets/icon.dart index c400239f8a..b490b0beda 100644 --- a/packages/flutter/lib/src/widgets/icon.dart +++ b/packages/flutter/lib/src/widgets/icon.dart @@ -89,7 +89,10 @@ class Icon extends StatelessWidget { /// This would be read out in accessibility modes (e.g TalkBack/VoiceOver). /// This label does not show in the UI. /// - /// See [Semantics.label]; + /// See also: + /// + /// * [Semantics.label] which is set with [semanticLabel] in the underlying + /// [Semantics] widget. final String semanticLabel; @override @@ -102,15 +105,19 @@ class Icon extends StatelessWidget { final double iconSize = size ?? iconTheme.size; if (icon == null) - return _wrapWithSemantics(new SizedBox(width: iconSize, height: iconSize)); + return new Semantics( + label: semanticLabel, + child: new SizedBox(width: iconSize, height: iconSize) + ); final double iconOpacity = iconTheme.opacity; Color iconColor = color ?? iconTheme.color; if (iconOpacity != 1.0) iconColor = iconColor.withOpacity(iconColor.opacity * iconOpacity); - return _wrapWithSemantics( - new ExcludeSemantics( + return new Semantics( + label: semanticLabel, + child: new ExcludeSemantics( child: new SizedBox( width: iconSize, height: iconSize, @@ -133,17 +140,6 @@ class Icon extends StatelessWidget { ); } - /// Wraps the widget with a Semantics widget if [semanticLabel] is set. - Widget _wrapWithSemantics(Widget widget) { - if (semanticLabel == null) - return widget; - - return new Semantics( - child: widget, - label: semanticLabel, - ); - } - @override void debugFillProperties(DiagnosticPropertiesBuilder description) { super.debugFillProperties(description); diff --git a/packages/flutter/test/widgets/icon_test.dart b/packages/flutter/test/widgets/icon_test.dart index 3f95d7557b..e2ebd543f4 100644 --- a/packages/flutter/test/widgets/icon_test.dart +++ b/packages/flutter/test/widgets/icon_test.dart @@ -161,4 +161,35 @@ void main() { expect(semantics, hasSemantics(new TestSemantics.root(label: 'a label'))); }); + + testWidgets('Changing semantic label from null doesn\'t rebuild tree ', (WidgetTester tester) async { + await tester.pumpWidget( + const Directionality( + textDirection: TextDirection.ltr, + child: const Center( + child: const Icon(Icons.time_to_leave), + ), + ), + ); + + final Element richText1 = tester.element(find.byType(RichText)); + + await tester.pumpWidget( + const Directionality( + textDirection: TextDirection.ltr, + child: const Center( + child: const Icon( + Icons.time_to_leave, + semanticLabel: 'a label', + ), + ), + ), + ); + + final Element richText2 = tester.element(find.byType(RichText)); + + // Compare a leaf Element in the Icon subtree before and after changing the + // semanticLabel to make sure the subtree was not rebuilt. + expect(richText2, same(richText1)); + }); }