Skip to content

Icon widget does not scale with textScaleFactor #115466

@mateusfccp

Description

@mateusfccp

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

  1. 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.

image

Possible solutions

I see some possible solutions to this issue:

  1. Change the default behavior, which is breaking and probably won't happen;
  2. Provide a new widget like TextScaleAwareIcon that would be tha same but considering the text scale;
  3. Provide a parameter in the Icon widget to make it consider the text scale;
  4. 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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    P3Issues that are less important to the Flutter projectc: new featureNothing broken; request for a new capabilityf: material designflutter/packages/flutter/material repository.found in release: 3.3Found to occur in 3.3found in release: 3.6Found to occur in 3.6frameworkflutter/packages/flutter repository. See also f: labels.has reproducible stepsThe issue has been confirmed reproducible and is ready to work onr: fixedIssue is closed as already fixed in a newer versionteam-designOwned by Design Languages teamtriaged-designTriaged by Design Languages team

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions