add semantic label to image icon and exclude semantics from image widget (#19970)
This commit is contained in:
parent
a201980223
commit
82415e6400
@ -26,7 +26,8 @@ class ImageIcon extends StatelessWidget {
|
||||
const ImageIcon(this.image, {
|
||||
Key key,
|
||||
this.size,
|
||||
this.color
|
||||
this.color,
|
||||
this.semanticLabel,
|
||||
}) : super(key: key);
|
||||
|
||||
/// The image to display as the icon.
|
||||
@ -53,14 +54,27 @@ class ImageIcon extends StatelessWidget {
|
||||
/// [IconTheme], if any.
|
||||
final Color color;
|
||||
|
||||
/// Semantic label for the icon.
|
||||
///
|
||||
/// Announced in accessibility modes (e.g TalkBack/VoiceOver).
|
||||
/// This label does not show in the UI.
|
||||
///
|
||||
/// See also:
|
||||
///
|
||||
/// * [Semantics.label], which is set to [semanticLabel] in the underlying
|
||||
/// [Semantics] widget.
|
||||
final String semanticLabel;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final IconThemeData iconTheme = IconTheme.of(context);
|
||||
|
||||
final double iconSize = size ?? iconTheme.size;
|
||||
|
||||
if (image == null)
|
||||
return new SizedBox(width: iconSize, height: iconSize);
|
||||
return new Semantics(
|
||||
label: semanticLabel,
|
||||
child: SizedBox(width: iconSize, height: iconSize)
|
||||
);
|
||||
|
||||
final double iconOpacity = iconTheme.opacity;
|
||||
Color iconColor = color ?? iconTheme.color;
|
||||
@ -68,13 +82,17 @@ class ImageIcon extends StatelessWidget {
|
||||
if (iconOpacity != null && iconOpacity != 1.0)
|
||||
iconColor = iconColor.withOpacity(iconColor.opacity * iconOpacity);
|
||||
|
||||
return new Image(
|
||||
image: image,
|
||||
width: iconSize,
|
||||
height: iconSize,
|
||||
color: iconColor,
|
||||
fit: BoxFit.scaleDown,
|
||||
alignment: Alignment.center,
|
||||
return new Semantics(
|
||||
label: semanticLabel,
|
||||
child: Image(
|
||||
image: image,
|
||||
width: iconSize,
|
||||
height: iconSize,
|
||||
color: iconColor,
|
||||
fit: BoxFit.scaleDown,
|
||||
alignment: Alignment.center,
|
||||
excludeFromSemantics: true,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -96,4 +96,26 @@ void main() {
|
||||
final RenderBox renderObject = tester.renderObject(find.byType(ImageIcon));
|
||||
expect(renderObject.size, equals(const Size.square(24.0)));
|
||||
});
|
||||
|
||||
testWidgets('ImageIcon has semantics data', (WidgetTester tester) async {
|
||||
final SemanticsHandle handle = tester.ensureSemantics();
|
||||
await tester.pumpWidget(
|
||||
const Directionality(
|
||||
textDirection: TextDirection.ltr,
|
||||
child: const Center(
|
||||
child: const IconTheme(
|
||||
data: const IconThemeData(),
|
||||
child: const ImageIcon(null, semanticLabel: 'test')
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
expect(tester.getSemanticsData(find.byType(ImageIcon)), matchesSemanticsData(
|
||||
label: 'test',
|
||||
textDirection: TextDirection.ltr,
|
||||
));
|
||||
handle.dispose();
|
||||
});
|
||||
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user