text_autosize 0.1.1
text_autosize: ^0.1.1 copied to clipboard
Automatically resize text to fit its bounds: shrink the font until the text fits the available width, height and maxLines. TextScaler-aware, API-compatible with auto_size_text.
[text_autosize]
text_autosize #
A Flutter widget that automatically resizes text to fit within its bounds.
The API follows the auto_size_text package by Simon Leier, so existing code
migrates by changing the import. On top of the familiar API, this package is
built against current Flutter releases and handles TextScaler correctly,
including nonlinear system font scaling.
Demo #
[demo]
Features #
- Shrinks text until it fits the available width, height and
maxLines. minFontSize,maxFontSizeandstepGranularitycontrol the search range.presetFontSizesrestricts the text to a fixed list of sizes.AutoSizeGroupkeeps several texts at the same size.AutoSizeText.richresizes a wholeTextSpantree proportionally.overflowReplacementswaps in another widget when nothing fits.textScaleraware: the fitted size accounts for the user's font scale.- Works inside
SelectionArea, since it builds a regularTextwidget.
Usage #
Requires Flutter 3.32 or later.
import 'package:text_autosize/text_autosize.dart';
AutoSizeText(
'The text to display',
style: TextStyle(fontSize: 20),
maxLines: 2,
)
The widget behaves like Text, except that it lowers the font size until the
text fits the incoming constraints. It needs bounded constraints to resize
against, for example from a SizedBox or an Expanded.
maxLines and minFontSize #
AutoSizeText(
'A single line that shrinks down to 10 before it ellipsizes',
style: TextStyle(fontSize: 30),
maxLines: 1,
minFontSize: 10,
overflow: TextOverflow.ellipsis,
)
Preset font sizes #
If only some sizes are allowed, pass them in descending order. The first size that fits is used:
AutoSizeText(
'One of three sizes',
presetFontSizes: [40, 20, 14],
maxLines: 1,
)
Synchronizing several texts #
Give all texts the same AutoSizeGroup. Every member renders at the size of
the most constrained one:
final group = AutoSizeGroup();
AutoSizeText('Label one', group: group, maxLines: 1);
AutoSizeText('A much longer label two', group: group, maxLines: 1);
Rich text #
AutoSizeText.rich(
TextSpan(
text: 'Mixed ',
children: [
TextSpan(text: 'sizes', style: TextStyle(fontSize: 40)),
],
),
style: TextStyle(fontSize: 20),
maxLines: 1,
)
All font sizes in the span tree are scaled by the same factor, so the proportions of the spans are preserved.
Overflow replacement #
AutoSizeText(
'A text that might not fit at minFontSize',
minFontSize: 16,
overflowReplacement: Text('Not enough room'),
)
Migration from auto_size_text #
-
Replace the dependency in
pubspec.yaml:dependencies: text_autosize: ^0.1.0 -
Replace the import. The class names
AutoSizeTextandAutoSizeGroupare unchanged:import 'package:text_autosize/text_autosize.dart'; -
Replace
textScaleFactorwithtextScaler:// before AutoSizeText('Hello', textScaleFactor: 1.5) // after AutoSizeText('Hello', textScaler: TextScaler.linear(1.5))
Intentional behavior differences from auto_size_text 3.0.0:
- The built
Textcarries the logical font size plus aTextScaler, instead of a pre-scaled font size with scaling disabled. The rendered pixels are identical; only the internal representation differs. Migrated tests that look up the innerTextthroughtextKeyand assert onstyle.fontSizesee the logical value now. - With a linear scaler,
minFontSize,maxFontSizeandpresetFontSizesproduce the same rendered size as the original package. The behavior only differs under a nonlinear scaler (for example Android 14 system font scaling), where the fitted size is computed with the actual scaler instead of a single factor. - Rich text is measured with the fully resolved style, exactly as
Text.richrenders it. The original measured the span's own style only, which could mismeasure spans that inherit their size fromDefaultTextStyle. - Measurement resolves
textAlignandtextDirectionthe same way the renderedTextdoes, instead of assuming left-aligned, left-to-right text. - An
AutoSizeGroupsynchronizes the logical font size of its members. Each member still applies its ownTextScalerwhen rendering. presetFontSizesmust be in descending order; this is now checked with an assert instead of being silently required.textWidthBasis,textHeightBehaviorandselectionColorare passed through to the builtText.
How it works #
The widget measures the text with a TextPainter against the incoming
constraints. If the preferred font size does not fit, a binary search runs
over the candidate sizes between minFontSize and the preferred size in
steps of stepGranularity, or over presetFontSizes if given. A build
therefore performs O(log n) text layouts for n candidate sizes, and a single
TextPainter instance is reused for all measurements.
Limitations #
- The widget only shrinks text below its preferred size. It does not grow
text to fill extra space, except through
presetFontSizes. - Resizing needs a bounded constraint. In an unbounded context, such as the
scroll direction of a
ListViewor inside anUnconstrainedBox, the text keeps its preferred size. This is safe but performs no resizing on that axis. - The widget is built around a
LayoutBuilder, so it cannot be used where intrinsic dimensions are required, for example insideIntrinsicWidthorIntrinsicHeight. strutStyleis passed through as given and is not resized with the text. A strut with a fixed font size puts a floor under the line height.softWrap: falseaffects rendering but not measurement, so text that is fitted with wrapping in mind can still overflow horizontally when soft wrapping is disabled. This matchesauto_size_text.- With
wrapWords: false, the longest-word check measures the words with the base style only. Per-span font sizes of rich text are not considered in that check. This also matchesauto_size_text.
Credits #
The API follows the auto_size_text package by Simon Leier.
License #
MIT. See LICENSE.