-
Notifications
You must be signed in to change notification settings - Fork 29.7k
Description
Description
The Icon widget does not scale with the context's textScaleFactor. I don't know why this happen, considering that, internally, Icon is also a text.
Because of this, we had to make a custom icon widget in our project, like:
class TextScaleAwareIcon extends StatelessWidget {
// Basically the same API as Icon except for `shouldScaleAccordingToTextScale` [...]
@override
Widget build(BuildContext context) {
final resolvedSize = size ?? IconTheme.of(context).size ?? kDefaultIconSize;
final iconSize = shouldScaleAccordingToTextScale //
? resolvedSize * MediaQuery.of(context).textScaleFactor
: resolvedSize;
return Icon(
icon,
size: iconSize,
color: color,
semanticLabel: semanticLabel,
textDirection: textDirection,
shadows: shadows,
);
}
}Alternatively, we would have to always multiply the text scale in our icons usage.
Icon(
Icons.something,
size: IconTheme.of(context).size! * MediaQuery.of(context).textScaleFactor,
),We use this widget in about 90% or more of the times we need an icon, because most of the time is what people expect. Example, in a button we expect that the icon of the button scales with the text scale factor.
Steps to Reproduce
- Run the following code:
import 'package:flutter/material.dart';
const Color darkBlue = Color.fromARGB(255, 18, 32, 47);
void main() {
runApp(App());
}
class App extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData.dark().copyWith(
scaffoldBackgroundColor: darkBlue,
),
debugShowCheckedModeBanner: false,
home: Scaffold(
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
TextRow(),
const SizedBox(height: 16.0),
MediaQuery(
data: const MediaQueryData(textScaleFactor: 2.0),
child: TextRow(),
),
],
),
),
),
);
}
}
class TextRow extends StatelessWidget {
static const fontSize = 14.0;
@override
Widget build(BuildContext context) {
return Row(
mainAxisSize: MainAxisSize.min,
children: [
Text(
'Hello, World!',
style: Theme.of(context)
.textTheme
.headline4
?.copyWith(fontSize: fontSize),
),
const SizedBox(width: 16.0),
const Icon(
Icons.format_color_text,
size: fontSize,
),
],
);
}
}Expected results:
The icon should be scaled just like the text.
Actual results:
The icon is not scaled.
Possible solutions
I see some possible solutions to this issue:
- Change the default behavior, which is breaking and probably won't happen;
- Provide a new widget like
TextScaleAwareIconthat would be tha same but considering the text scale; - Provide a parameter in the
Iconwidget to make it consider the text scale; - Provide a property in the icon theme to make it consider the text scale.
Personally, I think I would go with the theme option, as it would allow us to, for example, change this behavior for an entire tree by wrapping it in a new IconTheme that has it enabled.
