Skip to content
Boring Doc
DeprecatedMedium impactOfficial migration guidesince 3.16.0landed 3.13.0-4.0.preandroid

Deprecate textScaleFactor in favor of TextScaler

Framework · Official source

In preparation for adopting the Android 14 nonlinear font scaling feature, all occurrences of `textScaleFactor` in the Flutter framework have been deprecated and replaced by `TextScaler`.

Original behavior

Many platforms allow users to scale textual contents up or down globally in system preferences. In the past, the scaling strategy was captured as a single `double` value named `textScaleFactor`, as text scaling was proportional: `scaledFontSize = textScaleFactor x unScaledFontSize`. For example, when `textScaleFactor` is 2.0 and the developer-specified font size is 14.0, the actual font size is 2.0 x 14.0 = 28.0.

New behavior

Introducing a new interface `TextScaler`, which represents a text scaling strategy.

Who is affected
Affected APIs | Error Message |
Practical impact
Warnings now; removal in a future release. Plan the migration but no immediate break.
What action should I take?
Follow the official migration guide below, update affected call sites, run `dart fix --apply` where a fix is available, then run your tests.

Before and after (from the official guide)

dart+1−1
Before
1 abstract class _MyCustomPaintDelegate {
2− void paint(PaintingContext context, Offset offset, double textScaleFactor) {
3 }
4 }
After
1 abstract class _MyCustomPaintDelegate {
2+ void paint(PaintingContext context, Offset offset, TextScaler textScaler) {
3 }
4 }
Raw before / after
abstract class _MyCustomPaintDelegate {
  void paint(PaintingContext context, Offset offset, double textScaleFactor) {
  }
}
abstract class _MyCustomPaintDelegate {
  void paint(PaintingContext context, Offset offset, TextScaler textScaler) {
  }
}
Official migration guide (excerpt, © The Flutter Authors, CC BY 3.0)

Widgets provided by the Flutter framework are already migrated. Migration is needed only if you're using any of the deprecated symbols listed in the previous tables.

Migrating your APIs that expose textScaleFactor

Before:

abstract class _MyCustomPaintDelegate {
  void paint(PaintingContext context, Offset offset, double textScaleFactor) {
  }
}

After:

abstract class _MyCustomPaintDelegate {
  void paint(PaintingContext context, Offset offset, TextScaler textScaler) {
  }
}

Migrating code that consumes textScaleFactor

If you're not currently using textScaleFactor directly, but rather passing it to a different API that receives a textScaleFactor, and the receiver API has already been migrated, then it's relatively straightforward:

Before:

RichText(
  textScaleFactor: MediaQuery.textScaleFactorOf(context),
  ...
)

After:

RichText(
  textScaler: MediaQuery.textScalerOf(context),
  ...
)

If the API that provides textScaleFactor hasn't been migrated, consider waiting for the migrated version.

If you wish to compute the scaled font size yourself, use TextScaler.scale instead of the * binary operator:

Before:

final scaledFontSize = textStyle.fontSize * MediaQuery.textScaleFactorOf(context);

After:

final scaledFontSize = MediaQuery.textScalerOf(context).scale(textStyle.fontSize);

If you are using textScaleFactor to scale dimensions that are not font sizes, there are no generic rules for migrating the code to nonlinear scaling, and it might require the UI to be implemented differently. Reusing the MyTooltipBoxexample:

MyTooltipBox(
  size: chatBoxSize * textScaleFactor,
  child: RichText(..., style: TextStyle(fontSize: 20)),
)

You could choose to use the "effective" text scale factor by applying the TextScaler on the font size 20: chatBoxSize * textScaler.scale(20) / 20, or redesign the UI and let the widget assume its own intrinsic size.

Overriding the text scaling strategy in a widget subtree

To override the existing TextScaler used in a widget subtree, override the MediaQuery like so:

Before:

MediaQuery(
  data: MediaQuery.of(context).copyWith(textScaleFactor: 2.0),
  child: child,
)

After:

MediaQuery(
  data: MediaQuery.of(context).copyWith(textScaler: _myCustomTextScaler),
  child: child,
)

However, it's rarely needed to create a custom TextScaler subclass. MediaQuery.withNoTextScaling (which creates a widget that disables text scaling altogether for its child subtree), and MediaQuery.withClampedTextScaling (which creates a widget that restricts the scaled font size to within the range [minScaleFactor * fontSize, maxScaleFactor * fontSize]), are convenience methods that cover common cases where the text scaling strategy needs to be overridden.

Examples

Disabling Text Scaling For Icon Fonts

Before:

MediaQuery(
  data: MediaQuery.of(context).copyWith(textScaleFactor: 1.0),
  child: IconTheme(
    data: ..,
    child: icon,
  ),
)

After:

MediaQuery.withNoTextScaling(
  child: IconTheme(
    data: ...
    child: icon,
  ),
)

Preventing Contents From Overscaling

Before:

final mediaQueryData = MediaQuery.of(context);
MediaQuery(
  data: mediaQueryData.copyWith(textScaleFactor: math.min(mediaQueryData.textScaleFactor, _kMaxTitleTextScaleFactor),
  child: child,
)

After:

MediaQuery.withClampedTextScaling(
  maxScaleFactor: _kMaxTitleTextScaleFactor,
  child: title,
)

Disabling Nonlinear Text Scaling

If you want to temporarily opt-out of nonlinear text scaling on Android 14 until your app is fully migrated, put a modified MediaQuery at the top of your app's widget tree:

runApp(
  Builder(builder: (context) {
    final mediaQueryData = MediaQuery.of(context);
    final mediaQueryDataWithLinearTextScaling = mediaQueryData
      .copyWith(textScaler: TextScaler.linear(mediaQueryData.textScaler.textScaleFactor));
    return MediaQuery(data: mediaQueryDataWithLinearTextScaling, child: realWidgetTree);
  }),
);

This trick uses the deprecated textScaleFactor API and will stop working once it's removed from the Flutter API.

Migration assistantAI-generated · grounded in cited sources
AI explanations are not configured
Set AI_PROVIDER (for example to openai-compatible with a local Ollama or LM Studio endpoint) to enable grounded explanations. Everything else on this page works without an AI provider.
Official migration guide·Verified classification (90%)

Listed in the official breaking-changes index; title states deprecation.

An official announcement or migration guide documents an intended behaviour or API change. A verified source change (git diff) shows code changed but does not by itself prove a public API is breaking. AI interpretations are labelled and never used to classify a change.

Source commit
b3045439b7c0
Source last updated
Oct 21, 2026
Last synchronized
Oct 21, 2026
Publication status
published
Publication history
  • Oct 21, 2026, 8:31 PM: new → published (ingestion) — Backed by an official breaking-change/migration guide.
AI explanationAI-generated · grounded in cited sources
AI explanations are not configured
Set AI_PROVIDER (for example to openai-compatible with a local Ollama or LM Studio endpoint) to enable grounded explanations. Everything else on this page works without an AI provider.
Was this useful?