Remove more textScaleFactor references (#141816)

Remove more `textScaleFactor` references from flutter/flutter.  

- Some changes are related to label scaling: the padding EdgeInsets values of some chip subclasses scale linearly between predetermined "max" padding values and "min" padding values. Before they scale with the `textScaleFactor` scalar, now they scale with the font size and are still capped at the original "max" and "min" values.
- The rest of them are tests or size heuristics that depend on `textScaleFactor`, these are replaced by an effective text scale factor computed using a default font size (which is determined in a pretty random fashion, but it will only make a difference on Android 14+).

No API changes in this batch. There are still some references left that I intend to remove in a different batch that would introduce API changes.
This commit is contained in:
LongCatIsLooong 2024-01-19 16:27:18 -08:00 committed by GitHub
parent bc254ce3f5
commit 5892a0039b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
50 changed files with 421 additions and 296 deletions

View File

@ -83,16 +83,24 @@ class _${blockName}DefaultsM3 extends ChipThemeData {
@override @override
EdgeInsetsGeometry? get padding => const EdgeInsets.all(8.0); EdgeInsetsGeometry? get padding => const EdgeInsets.all(8.0);
/// The chip at text scale 1 starts with 8px on each side and as text scaling /// The label padding of the chip scales with the font size specified in the
/// gets closer to 2 the label padding is linearly interpolated from 8px to 4px. /// [labelStyle], and the system font size settings that scale font sizes
/// Once the widget has a text scaling of 2 or higher than the label padding /// globally.
/// remains 4px. ///
/// The chip at effective font size 14.0 starts with 8px on each side and as
/// the font size scales up to closer to 28.0, the label padding is linearly
/// interpolated from 8px to 4px. Once the label has a font size of 2 or
/// higher, label padding remains 4px.
@override @override
EdgeInsetsGeometry? get labelPadding => EdgeInsets.lerp( EdgeInsetsGeometry? get labelPadding {
const EdgeInsets.symmetric(horizontal: 8.0), final double fontSize = labelStyle?.fontSize ?? 14.0;
const EdgeInsets.symmetric(horizontal: 4.0), final double fontSizeRatio = MediaQuery.textScalerOf(context).scale(fontSize) / 14.0;
clampDouble(MediaQuery.textScalerOf(context).textScaleFactor - 1.0, 0.0, 1.0), return EdgeInsets.lerp(
)!; const EdgeInsets.symmetric(horizontal: 8.0),
const EdgeInsets.symmetric(horizontal: 4.0),
clampDouble(fontSizeRatio - 1.0, 0.0, 1.0),
)!;
}
} }
'''; ''';
} }

View File

@ -62,16 +62,24 @@ class _${blockName}DefaultsM3 extends ChipThemeData {
@override @override
EdgeInsetsGeometry? get padding => const EdgeInsets.all(8.0); EdgeInsetsGeometry? get padding => const EdgeInsets.all(8.0);
/// The chip at text scale 1 starts with 8px on each side and as text scaling /// The label padding of the chip scales with the font size specified in the
/// gets closer to 2, the label padding is linearly interpolated from 8px to 4px. /// [labelStyle], and the system font size settings that scale font sizes
/// Once the widget has a text scaling of 2 or higher than the label padding /// globally.
/// remains 4px. ///
/// The chip at effective font size 14.0 starts with 8px on each side and as
/// the font size scales up to closer to 28.0, the label padding is linearly
/// interpolated from 8px to 4px. Once the label has a font size of 2 or
/// higher, label padding remains 4px.
@override @override
EdgeInsetsGeometry? get labelPadding => EdgeInsets.lerp( EdgeInsetsGeometry? get labelPadding {
const EdgeInsets.symmetric(horizontal: 8.0), final double fontSize = labelStyle?.fontSize ?? 14.0;
const EdgeInsets.symmetric(horizontal: 4.0), final double fontSizeRatio = MediaQuery.textScalerOf(context).scale(fontSize) / 14.0;
clampDouble(MediaQuery.textScalerOf(context).textScaleFactor - 1.0, 0.0, 1.0), return EdgeInsets.lerp(
)!; const EdgeInsets.symmetric(horizontal: 8.0),
const EdgeInsets.symmetric(horizontal: 4.0),
clampDouble(fontSizeRatio - 1.0, 0.0, 1.0),
)!;
}
} }
'''; ''';
} }

View File

@ -100,16 +100,24 @@ class _${blockName}DefaultsM3 extends ChipThemeData {
@override @override
EdgeInsetsGeometry? get padding => const EdgeInsets.all(8.0); EdgeInsetsGeometry? get padding => const EdgeInsets.all(8.0);
/// The chip at text scale 1 starts with 8px on each side and as text scaling /// The label padding of the chip scales with the font size specified in the
/// gets closer to 2 the label padding is linearly interpolated from 8px to 4px. /// [labelStyle], and the system font size settings that scale font sizes
/// Once the widget has a text scaling of 2 or higher than the label padding /// globally.
/// remains 4px. ///
/// The chip at effective font size 14.0 starts with 8px on each side and as
/// the font size scales up to closer to 28.0, the label padding is linearly
/// interpolated from 8px to 4px. Once the label has a font size of 2 or
/// higher, label padding remains 4px.
@override @override
EdgeInsetsGeometry? get labelPadding => EdgeInsets.lerp( EdgeInsetsGeometry? get labelPadding {
const EdgeInsets.symmetric(horizontal: 8.0), final double fontSize = labelStyle?.fontSize ?? 14.0;
const EdgeInsets.symmetric(horizontal: 4.0), final double fontSizeRatio = MediaQuery.textScalerOf(context).scale(fontSize) / 14.0;
clampDouble(MediaQuery.textScalerOf(context).textScaleFactor - 1.0, 0.0, 1.0), return EdgeInsets.lerp(
)!; const EdgeInsets.symmetric(horizontal: 8.0),
const EdgeInsets.symmetric(horizontal: 4.0),
clampDouble(fontSizeRatio - 1.0, 0.0, 1.0),
)!;
}
} }
'''; ''';
} }

View File

@ -77,16 +77,24 @@ class _${blockName}DefaultsM3 extends ChipThemeData {
@override @override
EdgeInsetsGeometry? get padding => const EdgeInsets.all(8.0); EdgeInsetsGeometry? get padding => const EdgeInsets.all(8.0);
/// The chip at text scale 1 starts with 8px on each side and as text scaling /// The label padding of the chip scales with the font size specified in the
/// gets closer to 2 the label padding is linearly interpolated from 8px to 4px. /// [labelStyle], and the system font size settings that scale font sizes
/// Once the widget has a text scaling of 2 or higher than the label padding /// globally.
/// remains 4px. ///
/// The chip at effective font size 14.0 starts with 8px on each side and as
/// the font size scales up to closer to 28.0, the label padding is linearly
/// interpolated from 8px to 4px. Once the label has a font size of 2 or
/// higher, label padding remains 4px.
@override @override
EdgeInsetsGeometry? get labelPadding => EdgeInsets.lerp( EdgeInsetsGeometry? get labelPadding {
const EdgeInsets.symmetric(horizontal: 8.0), final double fontSize = labelStyle?.fontSize ?? 14.0;
const EdgeInsets.symmetric(horizontal: 4.0), final double fontSizeRatio = MediaQuery.textScalerOf(context).scale(fontSize) / 14.0;
clampDouble(MediaQuery.textScalerOf(context).textScaleFactor - 1.0, 0.0, 1.0), return EdgeInsets.lerp(
)!; const EdgeInsets.symmetric(horizontal: 8.0),
const EdgeInsets.symmetric(horizontal: 4.0),
clampDouble(fontSizeRatio - 1.0, 0.0, 1.0),
)!;
}
} }
'''; ''';
} }

View File

@ -200,6 +200,11 @@ class _MenuButtonDefaultsM3 extends ButtonStyle {
if (visualDensity.horizontal > 0) { if (visualDensity.horizontal > 0) {
visualDensity = VisualDensity(vertical: visualDensity.vertical); visualDensity = VisualDensity(vertical: visualDensity.vertical);
} }
// Since the threshold paddings used below are empirical values determined
// at a font size of 14.0, 14.0 is used as the base value for scaling the
// padding.
final double fontSize = Theme.of(context).textTheme.labelLarge?.fontSize ?? 14.0;
final double fontSizeRatio = MediaQuery.textScalerOf(context).scale(fontSize) / 14.0;
return ButtonStyleButton.scaledPadding( return ButtonStyleButton.scaledPadding(
EdgeInsets.symmetric(horizontal: math.max( EdgeInsets.symmetric(horizontal: math.max(
_kMenuViewPadding, _kMenuViewPadding,
@ -210,7 +215,7 @@ class _MenuButtonDefaultsM3 extends ButtonStyle {
8 + visualDensity.baseSizeAdjustment.dx, 8 + visualDensity.baseSizeAdjustment.dx,
)), )),
const EdgeInsets.symmetric(horizontal: _kMenuViewPadding), const EdgeInsets.symmetric(horizontal: _kMenuViewPadding),
MediaQuery.maybeTextScaleFactorOf(context) ?? 1, fontSizeRatio,
); );
} }
} }

View File

@ -149,8 +149,9 @@ const double _kMaxRegularTextScaleFactor = 1.4;
// Accessibility mode on iOS is determined by the text scale factor that the // Accessibility mode on iOS is determined by the text scale factor that the
// user has selected. // user has selected.
bool _isInAccessibilityMode(BuildContext context) { bool _isInAccessibilityMode(BuildContext context) {
final double? factor = MediaQuery.maybeTextScalerOf(context)?.textScaleFactor; const double defaultFontSize = 14.0;
return factor != null && factor > _kMaxRegularTextScaleFactor; final double? scaledFontSize = MediaQuery.maybeTextScalerOf(context)?.scale(defaultFontSize);
return scaledFontSize != null && scaledFontSize > defaultFontSize * _kMaxRegularTextScaleFactor;
} }
/// An iOS-style alert dialog. /// An iOS-style alert dialog.
@ -264,7 +265,8 @@ class _CupertinoAlertDialogState extends State<CupertinoAlertDialog> {
widget.actionScrollController ?? (_backupActionScrollController ??= ScrollController()); widget.actionScrollController ?? (_backupActionScrollController ??= ScrollController());
Widget _buildContent(BuildContext context) { Widget _buildContent(BuildContext context) {
final double textScaleFactor = MediaQuery.textScalerOf(context).textScaleFactor; const double defaultFontSize = 14.0;
final double effectiveTextScaleFactor = MediaQuery.textScalerOf(context).scale(defaultFontSize) / defaultFontSize;
final List<Widget> children = <Widget>[ final List<Widget> children = <Widget>[
if (widget.title != null || widget.content != null) if (widget.title != null || widget.content != null)
@ -278,12 +280,12 @@ class _CupertinoAlertDialogState extends State<CupertinoAlertDialog> {
left: _kDialogEdgePadding, left: _kDialogEdgePadding,
right: _kDialogEdgePadding, right: _kDialogEdgePadding,
bottom: widget.content == null ? _kDialogEdgePadding : 1.0, bottom: widget.content == null ? _kDialogEdgePadding : 1.0,
top: _kDialogEdgePadding * textScaleFactor, top: _kDialogEdgePadding * effectiveTextScaleFactor,
), ),
messagePadding: EdgeInsets.only( messagePadding: EdgeInsets.only(
left: _kDialogEdgePadding, left: _kDialogEdgePadding,
right: _kDialogEdgePadding, right: _kDialogEdgePadding,
bottom: _kDialogEdgePadding * textScaleFactor, bottom: _kDialogEdgePadding * effectiveTextScaleFactor,
top: widget.title == null ? _kDialogEdgePadding : 1.0, top: widget.title == null ? _kDialogEdgePadding : 1.0,
), ),
titleTextStyle: _kCupertinoDialogTitleStyle.copyWith( titleTextStyle: _kCupertinoDialogTitleStyle.copyWith(
@ -1653,10 +1655,6 @@ class CupertinoDialogAction extends StatelessWidget {
/// value. /// value.
bool get enabled => onPressed != null; bool get enabled => onPressed != null;
double _calculatePadding(BuildContext context) {
return 8.0 * MediaQuery.textScalerOf(context).textScaleFactor;
}
// Dialog action content shrinks to fit, up to a certain point, and if it still // Dialog action content shrinks to fit, up to a certain point, and if it still
// cannot fit at the minimum size, the text content is ellipsized. // cannot fit at the minimum size, the text content is ellipsized.
// //
@ -1665,6 +1663,7 @@ class CupertinoDialogAction extends StatelessWidget {
required BuildContext context, required BuildContext context,
required TextStyle textStyle, required TextStyle textStyle,
required Widget content, required Widget content,
required double padding,
}) { }) {
final bool isInAccessibilityMode = _isInAccessibilityMode(context); final bool isInAccessibilityMode = _isInAccessibilityMode(context);
final double dialogWidth = isInAccessibilityMode final double dialogWidth = isInAccessibilityMode
@ -1675,7 +1674,6 @@ class CupertinoDialogAction extends StatelessWidget {
// buttons. This ratio information is used to automatically scale down action // buttons. This ratio information is used to automatically scale down action
// button text to fit the available space. // button text to fit the available space.
final double fontSizeRatio = MediaQuery.textScalerOf(context).scale(textStyle.fontSize!) / _kDialogMinButtonFontSize; final double fontSizeRatio = MediaQuery.textScalerOf(context).scale(textStyle.fontSize!) / _kDialogMinButtonFontSize;
final double padding = _calculatePadding(context);
return IntrinsicHeight( return IntrinsicHeight(
child: SizedBox( child: SizedBox(
@ -1724,8 +1722,7 @@ class CupertinoDialogAction extends StatelessWidget {
isDestructiveAction ? CupertinoColors.systemRed : CupertinoTheme.of(context).primaryColor, isDestructiveAction ? CupertinoColors.systemRed : CupertinoTheme.of(context).primaryColor,
context, context,
), ),
); ).merge(textStyle);
style = style.merge(textStyle);
if (isDefaultAction) { if (isDefaultAction) {
style = style.copyWith(fontWeight: FontWeight.w600); style = style.copyWith(fontWeight: FontWeight.w600);
@ -1734,7 +1731,10 @@ class CupertinoDialogAction extends StatelessWidget {
if (!enabled) { if (!enabled) {
style = style.copyWith(color: style.color!.withOpacity(0.5)); style = style.copyWith(color: style.color!.withOpacity(0.5));
} }
final double fontSize = style.fontSize ?? kDefaultFontSize;
final double fontSizeToScale = fontSize == 0.0 ? kDefaultFontSize : fontSize;
final double effectiveTextScale = MediaQuery.textScalerOf(context).scale(fontSizeToScale) / fontSizeToScale;
final double padding = 8.0 * effectiveTextScale;
// Apply a sizing policy to the action button's content based on whether or // Apply a sizing policy to the action button's content based on whether or
// not the device is in accessibility mode. // not the device is in accessibility mode.
// TODO(mattcarroll): The following logic is not entirely correct. It is also // TODO(mattcarroll): The following logic is not entirely correct. It is also
@ -1750,6 +1750,7 @@ class CupertinoDialogAction extends StatelessWidget {
context: context, context: context,
textStyle: style, textStyle: style,
content: child, content: child,
padding: padding,
); );
return MouseRegion( return MouseRegion(
@ -1764,7 +1765,7 @@ class CupertinoDialogAction extends StatelessWidget {
), ),
child: Container( child: Container(
alignment: Alignment.center, alignment: Alignment.center,
padding: EdgeInsets.all(_calculatePadding(context)), padding: EdgeInsets.all(padding),
child: sizedContent, child: sizedContent,
), ),
), ),

View File

@ -408,7 +408,7 @@ class _CupertinoSearchTextFieldState extends State<CupertinoSearchTextField>
// The icon size will be scaled by a factor of the accessibility text scale, // The icon size will be scaled by a factor of the accessibility text scale,
// to follow the behavior of `UISearchTextField`. // to follow the behavior of `UISearchTextField`.
final double scaledIconSize = MediaQuery.textScalerOf(context).textScaleFactor * widget.itemSize; final double scaledIconSize = MediaQuery.textScalerOf(context).scale(widget.itemSize);
// If decoration was not provided, create a decoration with the provided // If decoration was not provided, create a decoration with the provided
// background color and border radius. // background color and border radius.

View File

@ -304,16 +304,24 @@ class _ActionChipDefaultsM3 extends ChipThemeData {
@override @override
EdgeInsetsGeometry? get padding => const EdgeInsets.all(8.0); EdgeInsetsGeometry? get padding => const EdgeInsets.all(8.0);
/// The chip at text scale 1 starts with 8px on each side and as text scaling /// The label padding of the chip scales with the font size specified in the
/// gets closer to 2 the label padding is linearly interpolated from 8px to 4px. /// [labelStyle], and the system font size settings that scale font sizes
/// Once the widget has a text scaling of 2 or higher than the label padding /// globally.
/// remains 4px. ///
/// The chip at effective font size 14.0 starts with 8px on each side and as
/// the font size scales up to closer to 28.0, the label padding is linearly
/// interpolated from 8px to 4px. Once the label has a font size of 2 or
/// higher, label padding remains 4px.
@override @override
EdgeInsetsGeometry? get labelPadding => EdgeInsets.lerp( EdgeInsetsGeometry? get labelPadding {
const EdgeInsets.symmetric(horizontal: 8.0), final double fontSize = labelStyle?.fontSize ?? 14.0;
const EdgeInsets.symmetric(horizontal: 4.0), final double fontSizeRatio = MediaQuery.textScalerOf(context).scale(fontSize) / 14.0;
clampDouble(MediaQuery.textScalerOf(context).textScaleFactor - 1.0, 0.0, 1.0), return EdgeInsets.lerp(
)!; const EdgeInsets.symmetric(horizontal: 8.0),
const EdgeInsets.symmetric(horizontal: 4.0),
clampDouble(fontSizeRatio - 1.0, 0.0, 1.0),
)!;
}
} }
// END GENERATED TOKEN PROPERTIES - ActionChip // END GENERATED TOKEN PROPERTIES - ActionChip

View File

@ -1158,16 +1158,6 @@ class _RawChipState extends State<RawChip> with MaterialStateMixin, TickerProvid
assert(debugCheckHasDirectionality(context)); assert(debugCheckHasDirectionality(context));
assert(debugCheckHasMaterialLocalizations(context)); assert(debugCheckHasMaterialLocalizations(context));
/// The chip at text scale 1 starts with 8px on each side and as text scaling
/// gets closer to 2 the label padding is linearly interpolated from 8px to 4px.
/// Once the widget has a text scaling of 2 or higher than the label padding
/// remains 4px.
final EdgeInsetsGeometry defaultLabelPadding = EdgeInsets.lerp(
const EdgeInsets.symmetric(horizontal: 8.0),
const EdgeInsets.symmetric(horizontal: 4.0),
clampDouble(MediaQuery.textScalerOf(context).textScaleFactor - 1.0, 0.0, 1.0),
)!;
final ThemeData theme = Theme.of(context); final ThemeData theme = Theme.of(context);
final ChipThemeData chipTheme = ChipTheme.of(context); final ChipThemeData chipTheme = ChipTheme.of(context);
final Brightness brightness = chipTheme.brightness ?? theme.brightness; final Brightness brightness = chipTheme.brightness ?? theme.brightness;
@ -1212,10 +1202,6 @@ class _RawChipState extends State<RawChip> with MaterialStateMixin, TickerProvid
// Widget's label style is merged with this below. // Widget's label style is merged with this below.
final TextStyle labelStyle = chipTheme.labelStyle final TextStyle labelStyle = chipTheme.labelStyle
?? chipDefaults.labelStyle!; ?? chipDefaults.labelStyle!;
final EdgeInsetsGeometry labelPadding = widget.labelPadding
?? chipTheme.labelPadding
?? chipDefaults.labelPadding
?? defaultLabelPadding;
final IconThemeData? iconTheme = widget.iconTheme final IconThemeData? iconTheme = widget.iconTheme
?? chipTheme.iconTheme ?? chipTheme.iconTheme
?? chipDefaults.iconTheme; ?? chipDefaults.iconTheme;
@ -1230,6 +1216,23 @@ class _RawChipState extends State<RawChip> with MaterialStateMixin, TickerProvid
) )
: widget.avatar; : widget.avatar;
/// The chip at text scale 1 starts with 8px on each side and as text scaling
/// gets closer to 2 the label padding is linearly interpolated from 8px to 4px.
/// Once the widget has a text scaling of 2 or higher than the label padding
/// remains 4px.
final double defaultFontSize = effectiveLabelStyle.fontSize ?? 14.0;
final double effectiveTextScale = MediaQuery.textScalerOf(context).scale(defaultFontSize) / 14.0;
final EdgeInsetsGeometry defaultLabelPadding = EdgeInsets.lerp(
const EdgeInsets.symmetric(horizontal: 8.0),
const EdgeInsets.symmetric(horizontal: 4.0),
clampDouble(effectiveTextScale - 1.0, 0.0, 1.0),
)!;
final EdgeInsetsGeometry labelPadding = widget.labelPadding
?? chipTheme.labelPadding
?? chipDefaults.labelPadding
?? defaultLabelPadding;
Widget result = Material( Widget result = Material(
elevation: isTapping ? pressElevation : elevation, elevation: isTapping ? pressElevation : elevation,
shadowColor: widget.selected ? selectedShadowColor : shadowColor, shadowColor: widget.selected ? selectedShadowColor : shadowColor,
@ -2319,16 +2322,24 @@ class _ChipDefaultsM3 extends ChipThemeData {
@override @override
EdgeInsetsGeometry? get padding => const EdgeInsets.all(8.0); EdgeInsetsGeometry? get padding => const EdgeInsets.all(8.0);
/// The chip at text scale 1 starts with 8px on each side and as text scaling /// The label padding of the chip scales with the font size specified in the
/// gets closer to 2, the label padding is linearly interpolated from 8px to 4px. /// [labelStyle], and the system font size settings that scale font sizes
/// Once the widget has a text scaling of 2 or higher than the label padding /// globally.
/// remains 4px. ///
/// The chip at effective font size 14.0 starts with 8px on each side and as
/// the font size scales up to closer to 28.0, the label padding is linearly
/// interpolated from 8px to 4px. Once the label has a font size of 2 or
/// higher, label padding remains 4px.
@override @override
EdgeInsetsGeometry? get labelPadding => EdgeInsets.lerp( EdgeInsetsGeometry? get labelPadding {
const EdgeInsets.symmetric(horizontal: 8.0), final double fontSize = labelStyle?.fontSize ?? 14.0;
const EdgeInsets.symmetric(horizontal: 4.0), final double fontSizeRatio = MediaQuery.textScalerOf(context).scale(fontSize) / 14.0;
clampDouble(MediaQuery.textScalerOf(context).textScaleFactor - 1.0, 0.0, 1.0), return EdgeInsets.lerp(
)!; const EdgeInsets.symmetric(horizontal: 8.0),
const EdgeInsets.symmetric(horizontal: 4.0),
clampDouble(fontSizeRatio - 1.0, 0.0, 1.0),
)!;
}
} }
// END GENERATED TOKEN PROPERTIES - Chip // END GENERATED TOKEN PROPERTIES - Chip

View File

@ -329,16 +329,24 @@ class _ChoiceChipDefaultsM3 extends ChipThemeData {
@override @override
EdgeInsetsGeometry? get padding => const EdgeInsets.all(8.0); EdgeInsetsGeometry? get padding => const EdgeInsets.all(8.0);
/// The chip at text scale 1 starts with 8px on each side and as text scaling /// The label padding of the chip scales with the font size specified in the
/// gets closer to 2 the label padding is linearly interpolated from 8px to 4px. /// [labelStyle], and the system font size settings that scale font sizes
/// Once the widget has a text scaling of 2 or higher than the label padding /// globally.
/// remains 4px. ///
/// The chip at effective font size 14.0 starts with 8px on each side and as
/// the font size scales up to closer to 28.0, the label padding is linearly
/// interpolated from 8px to 4px. Once the label has a font size of 2 or
/// higher, label padding remains 4px.
@override @override
EdgeInsetsGeometry? get labelPadding => EdgeInsets.lerp( EdgeInsetsGeometry? get labelPadding {
const EdgeInsets.symmetric(horizontal: 8.0), final double fontSize = labelStyle?.fontSize ?? 14.0;
const EdgeInsets.symmetric(horizontal: 4.0), final double fontSizeRatio = MediaQuery.textScalerOf(context).scale(fontSize) / 14.0;
clampDouble(MediaQuery.textScalerOf(context).textScaleFactor - 1.0, 0.0, 1.0), return EdgeInsets.lerp(
)!; const EdgeInsets.symmetric(horizontal: 8.0),
const EdgeInsets.symmetric(horizontal: 4.0),
clampDouble(fontSizeRatio - 1.0, 0.0, 1.0),
)!;
}
} }
// END GENERATED TOKEN PROPERTIES - ChoiceChip // END GENERATED TOKEN PROPERTIES - ChoiceChip

View File

@ -659,7 +659,9 @@ class _DatePickerDialogState extends State<DatePickerDialog> with RestorationMix
// Constrain the textScaleFactor to the largest supported value to prevent // Constrain the textScaleFactor to the largest supported value to prevent
// layout issues. // layout issues.
final double textScaleFactor = MediaQuery.textScalerOf(context).clamp(maxScaleFactor: _kMaxTextScaleFactor).textScaleFactor; // 14 is a common font size used to compute the effective text scale.
const double fontSizeToScale = 14.0;
final double textScaleFactor = MediaQuery.textScalerOf(context).clamp(maxScaleFactor: _kMaxTextScaleFactor).scale(fontSizeToScale) / fontSizeToScale;
final Size dialogSize = _dialogSize(context) * textScaleFactor; final Size dialogSize = _dialogSize(context) * textScaleFactor;
final DialogTheme dialogTheme = theme.dialogTheme; final DialogTheme dialogTheme = theme.dialogTheme;
return Dialog( return Dialog(
@ -2874,7 +2876,9 @@ class _InputDateRangePickerDialog extends StatelessWidget {
), ),
); );
final double textScaleFactor = MediaQuery.textScalerOf(context).clamp(maxScaleFactor: _kMaxTextScaleFactor).textScaleFactor; // 14 is a common font size used to compute the effective text scale.
const double fontSizeToScale = 14.0;
final double textScaleFactor = MediaQuery.textScalerOf(context).clamp(maxScaleFactor: _kMaxTextScaleFactor).scale(fontSizeToScale) / fontSizeToScale;
final Size dialogSize = (useMaterial3 ? _inputPortraitDialogSizeM3 : _inputPortraitDialogSizeM2) * textScaleFactor; final Size dialogSize = (useMaterial3 ? _inputPortraitDialogSizeM3 : _inputPortraitDialogSizeM2) * textScaleFactor;
switch (orientation) { switch (orientation) {
case Orientation.portrait: case Orientation.portrait:

View File

@ -718,7 +718,9 @@ class AlertDialog extends StatelessWidget {
// The paddingScaleFactor is used to adjust the padding of Dialog's // The paddingScaleFactor is used to adjust the padding of Dialog's
// children. // children.
final double paddingScaleFactor = _paddingScaleFactor(MediaQuery.textScalerOf(context).textScaleFactor); const double fontSizeToScale = 14.0;
final double effectiveTextScale = MediaQuery.textScalerOf(context).scale(fontSizeToScale) / fontSizeToScale;
final double paddingScaleFactor = _scalePadding(effectiveTextScale);
final TextDirection? textDirection = Directionality.maybeOf(context); final TextDirection? textDirection = Directionality.maybeOf(context);
Widget? iconWidget; Widget? iconWidget;
@ -1213,7 +1215,11 @@ class SimpleDialog extends StatelessWidget {
// The paddingScaleFactor is used to adjust the padding of Dialog // The paddingScaleFactor is used to adjust the padding of Dialog
// children. // children.
final double paddingScaleFactor = _paddingScaleFactor(MediaQuery.textScalerOf(context).textScaleFactor); final TextStyle defaultTextStyle = titleTextStyle ?? DialogTheme.of(context).titleTextStyle ?? theme.textTheme.titleLarge!;
final double fontSize = defaultTextStyle.fontSize ?? kDefaultFontSize;
final double fontSizeToScale = fontSize == 0.0 ? kDefaultFontSize : fontSize;
final double effectiveTextScale = MediaQuery.textScalerOf(context).scale(fontSizeToScale) / fontSizeToScale;
final double paddingScaleFactor = _scalePadding(effectiveTextScale);
final TextDirection? textDirection = Directionality.maybeOf(context); final TextDirection? textDirection = Directionality.maybeOf(context);
Widget? titleWidget; Widget? titleWidget;
@ -1227,7 +1233,7 @@ class SimpleDialog extends StatelessWidget {
bottom: children == null ? effectiveTitlePadding.bottom * paddingScaleFactor : effectiveTitlePadding.bottom, bottom: children == null ? effectiveTitlePadding.bottom * paddingScaleFactor : effectiveTitlePadding.bottom,
), ),
child: DefaultTextStyle( child: DefaultTextStyle(
style: titleTextStyle ?? DialogTheme.of(context).titleTextStyle ?? theme.textTheme.titleLarge!, style: defaultTextStyle,
child: Semantics( child: Semantics(
// For iOS platform, the focus always lands on the title. // For iOS platform, the focus always lands on the title.
// Set nameRoute to false to avoid title being announce twice. // Set nameRoute to false to avoid title being announce twice.
@ -1577,7 +1583,7 @@ class DialogRoute<T> extends RawDialogRoute<T> {
); );
} }
double _paddingScaleFactor(double textScaleFactor) { double _scalePadding(double textScaleFactor) {
final double clampedTextScaleFactor = clampDouble(textScaleFactor, 1.0, 2.0); final double clampedTextScaleFactor = clampDouble(textScaleFactor, 1.0, 2.0);
// The final padding scale factor is clamped between 1/3 and 1. For example, // The final padding scale factor is clamped between 1/3 and 1. For example,
// a non-scaled padding of 24 will produce a padding between 24 and 8. // a non-scaled padding of 24 will produce a padding between 24 and 8.

View File

@ -2,7 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
import 'dart:math' as math;
import 'dart:ui' show lerpDouble; import 'dart:ui' show lerpDouble;
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
@ -483,7 +482,7 @@ class _ElevatedButtonWithIcon extends ElevatedButton {
}) : super( }) : super(
autofocus: autofocus ?? false, autofocus: autofocus ?? false,
clipBehavior: clipBehavior ?? Clip.none, clipBehavior: clipBehavior ?? Clip.none,
child: _ElevatedButtonWithIconChild(icon: icon, label: label), child: _ElevatedButtonWithIconChild(icon: icon, label: label, buttonStyle: style),
); );
@override @override
@ -512,15 +511,17 @@ class _ElevatedButtonWithIcon extends ElevatedButton {
} }
class _ElevatedButtonWithIconChild extends StatelessWidget { class _ElevatedButtonWithIconChild extends StatelessWidget {
const _ElevatedButtonWithIconChild({ required this.label, required this.icon }); const _ElevatedButtonWithIconChild({ required this.label, required this.icon, required this.buttonStyle });
final Widget label; final Widget label;
final Widget icon; final Widget icon;
final ButtonStyle? buttonStyle;
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final double scale = MediaQuery.textScalerOf(context).textScaleFactor; final double defaultFontSize = buttonStyle?.textStyle?.resolve(const <MaterialState>{})?.fontSize ?? 14.0;
final double gap = scale <= 1 ? 8 : lerpDouble(8, 4, math.min(scale - 1, 1))!; final double scale = clampDouble(MediaQuery.textScalerOf(context).scale(defaultFontSize) / 14.0, 1.0, 2.0) - 1.0;
final double gap = lerpDouble(8, 4, scale)!;
return Row( return Row(
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
children: <Widget>[icon, SizedBox(width: gap), Flexible(child: label)], children: <Widget>[icon, SizedBox(width: gap), Flexible(child: label)],

View File

@ -2,7 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
import 'dart:math' as math;
import 'dart:ui' show lerpDouble; import 'dart:ui' show lerpDouble;
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
@ -476,7 +475,7 @@ class _FilledButtonWithIcon extends FilledButton {
}) : super( }) : super(
autofocus: autofocus ?? false, autofocus: autofocus ?? false,
clipBehavior: clipBehavior ?? Clip.none, clipBehavior: clipBehavior ?? Clip.none,
child: _FilledButtonWithIconChild(icon: icon, label: label) child: _FilledButtonWithIconChild(icon: icon, label: label, buttonStyle: style),
); );
_FilledButtonWithIcon.tonal({ _FilledButtonWithIcon.tonal({
@ -495,7 +494,7 @@ class _FilledButtonWithIcon extends FilledButton {
}) : super.tonal( }) : super.tonal(
autofocus: autofocus ?? false, autofocus: autofocus ?? false,
clipBehavior: clipBehavior ?? Clip.none, clipBehavior: clipBehavior ?? Clip.none,
child: _FilledButtonWithIconChild(icon: icon, label: label) child: _FilledButtonWithIconChild(icon: icon, label: label, buttonStyle: style),
); );
@override @override
@ -524,17 +523,19 @@ class _FilledButtonWithIcon extends FilledButton {
} }
class _FilledButtonWithIconChild extends StatelessWidget { class _FilledButtonWithIconChild extends StatelessWidget {
const _FilledButtonWithIconChild({ required this.label, required this.icon }); const _FilledButtonWithIconChild({ required this.label, required this.icon, required this.buttonStyle });
final Widget label; final Widget label;
final Widget icon; final Widget icon;
final ButtonStyle? buttonStyle;
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final double scale = MediaQuery.textScalerOf(context).textScaleFactor; final double defaultFontSize = buttonStyle?.textStyle?.resolve(const <MaterialState>{})?.fontSize ?? 14.0;
final double scale = clampDouble(MediaQuery.textScalerOf(context).scale(defaultFontSize) / 14.0, 1.0, 2.0) - 1.0;
// Adjust the gap based on the text scale factor. Start at 8, and lerp // Adjust the gap based on the text scale factor. Start at 8, and lerp
// to 4 based on how large the text is. // to 4 based on how large the text is.
final double gap = scale <= 1 ? 8 : lerpDouble(8, 4, math.min(scale - 1, 1))!; final double gap = lerpDouble(8, 4, scale)!;
return Row( return Row(
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
children: <Widget>[icon, SizedBox(width: gap), Flexible(child: label)], children: <Widget>[icon, SizedBox(width: gap), Flexible(child: label)],

View File

@ -355,16 +355,24 @@ class _FilterChipDefaultsM3 extends ChipThemeData {
@override @override
EdgeInsetsGeometry? get padding => const EdgeInsets.all(8.0); EdgeInsetsGeometry? get padding => const EdgeInsets.all(8.0);
/// The chip at text scale 1 starts with 8px on each side and as text scaling /// The label padding of the chip scales with the font size specified in the
/// gets closer to 2 the label padding is linearly interpolated from 8px to 4px. /// [labelStyle], and the system font size settings that scale font sizes
/// Once the widget has a text scaling of 2 or higher than the label padding /// globally.
/// remains 4px. ///
/// The chip at effective font size 14.0 starts with 8px on each side and as
/// the font size scales up to closer to 28.0, the label padding is linearly
/// interpolated from 8px to 4px. Once the label has a font size of 2 or
/// higher, label padding remains 4px.
@override @override
EdgeInsetsGeometry? get labelPadding => EdgeInsets.lerp( EdgeInsetsGeometry? get labelPadding {
const EdgeInsets.symmetric(horizontal: 8.0), final double fontSize = labelStyle?.fontSize ?? 14.0;
const EdgeInsets.symmetric(horizontal: 4.0), final double fontSizeRatio = MediaQuery.textScalerOf(context).scale(fontSize) / 14.0;
clampDouble(MediaQuery.textScalerOf(context).textScaleFactor - 1.0, 0.0, 1.0), return EdgeInsets.lerp(
)!; const EdgeInsets.symmetric(horizontal: 8.0),
const EdgeInsets.symmetric(horizontal: 4.0),
clampDouble(fontSizeRatio - 1.0, 0.0, 1.0),
)!;
}
} }
// END GENERATED TOKEN PROPERTIES - FilterChip // END GENERATED TOKEN PROPERTIES - FilterChip

View File

@ -310,16 +310,24 @@ class _InputChipDefaultsM3 extends ChipThemeData {
@override @override
EdgeInsetsGeometry? get padding => const EdgeInsets.all(8.0); EdgeInsetsGeometry? get padding => const EdgeInsets.all(8.0);
/// The chip at text scale 1 starts with 8px on each side and as text scaling /// The label padding of the chip scales with the font size specified in the
/// gets closer to 2 the label padding is linearly interpolated from 8px to 4px. /// [labelStyle], and the system font size settings that scale font sizes
/// Once the widget has a text scaling of 2 or higher than the label padding /// globally.
/// remains 4px. ///
/// The chip at effective font size 14.0 starts with 8px on each side and as
/// the font size scales up to closer to 28.0, the label padding is linearly
/// interpolated from 8px to 4px. Once the label has a font size of 2 or
/// higher, label padding remains 4px.
@override @override
EdgeInsetsGeometry? get labelPadding => EdgeInsets.lerp( EdgeInsetsGeometry? get labelPadding {
const EdgeInsets.symmetric(horizontal: 8.0), final double fontSize = labelStyle?.fontSize ?? 14.0;
const EdgeInsets.symmetric(horizontal: 4.0), final double fontSizeRatio = MediaQuery.textScalerOf(context).scale(fontSize) / 14.0;
clampDouble(MediaQuery.textScalerOf(context).textScaleFactor - 1.0, 0.0, 1.0), return EdgeInsets.lerp(
)!; const EdgeInsets.symmetric(horizontal: 8.0),
const EdgeInsets.symmetric(horizontal: 4.0),
clampDouble(fontSizeRatio - 1.0, 0.0, 1.0),
)!;
}
} }
// END GENERATED TOKEN PROPERTIES - InputChip // END GENERATED TOKEN PROPERTIES - InputChip

View File

@ -2416,7 +2416,7 @@ class _InputDecoratorState extends State<InputDecorator> with TickerProviderStat
contentPadding = decorationContentPadding ?? EdgeInsets.zero; contentPadding = decorationContentPadding ?? EdgeInsets.zero;
} else if (!border.isOutline) { } else if (!border.isOutline) {
// 4.0: the vertical gap between the inline elements and the floating label. // 4.0: the vertical gap between the inline elements and the floating label.
floatingLabelHeight = (4.0 + 0.75 * labelStyle.fontSize!) * MediaQuery.textScalerOf(context).textScaleFactor; floatingLabelHeight = MediaQuery.textScalerOf(context).scale(4.0 + 0.75 * labelStyle.fontSize!);
if (decoration.filled ?? false) { if (decoration.filled ?? false) {
contentPadding = decorationContentPadding ?? (decorationIsDense contentPadding = decorationContentPadding ?? (decorationIsDense
? const EdgeInsets.fromLTRB(12.0, 8.0, 12.0, 8.0) ? const EdgeInsets.fromLTRB(12.0, 8.0, 12.0, 8.0)

View File

@ -3903,6 +3903,11 @@ class _MenuButtonDefaultsM3 extends ButtonStyle {
if (visualDensity.horizontal > 0) { if (visualDensity.horizontal > 0) {
visualDensity = VisualDensity(vertical: visualDensity.vertical); visualDensity = VisualDensity(vertical: visualDensity.vertical);
} }
// Since the threshold paddings used below are empirical values determined
// at a font size of 14.0, 14.0 is used as the base value for scaling the
// padding.
final double fontSize = Theme.of(context).textTheme.labelLarge?.fontSize ?? 14.0;
final double fontSizeRatio = MediaQuery.textScalerOf(context).scale(fontSize) / 14.0;
return ButtonStyleButton.scaledPadding( return ButtonStyleButton.scaledPadding(
EdgeInsets.symmetric(horizontal: math.max( EdgeInsets.symmetric(horizontal: math.max(
_kMenuViewPadding, _kMenuViewPadding,
@ -3913,7 +3918,7 @@ class _MenuButtonDefaultsM3 extends ButtonStyle {
8 + visualDensity.baseSizeAdjustment.dx, 8 + visualDensity.baseSizeAdjustment.dx,
)), )),
const EdgeInsets.symmetric(horizontal: _kMenuViewPadding), const EdgeInsets.symmetric(horizontal: _kMenuViewPadding),
MediaQuery.maybeTextScaleFactorOf(context) ?? 1, fontSizeRatio,
); );
} }
} }

View File

@ -2,7 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
import 'dart:math' as math;
import 'dart:ui' show lerpDouble; import 'dart:ui' show lerpDouble;
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
@ -414,7 +413,7 @@ class _OutlinedButtonWithIcon extends OutlinedButton {
}) : super( }) : super(
autofocus: autofocus ?? false, autofocus: autofocus ?? false,
clipBehavior: clipBehavior ?? Clip.none, clipBehavior: clipBehavior ?? Clip.none,
child: _OutlinedButtonWithIconChild(icon: icon, label: label), child: _OutlinedButtonWithIconChild(icon: icon, label: label, buttonStyle: style),
); );
@override @override
@ -442,15 +441,18 @@ class _OutlinedButtonWithIconChild extends StatelessWidget {
const _OutlinedButtonWithIconChild({ const _OutlinedButtonWithIconChild({
required this.label, required this.label,
required this.icon, required this.icon,
required this.buttonStyle,
}); });
final Widget label; final Widget label;
final Widget icon; final Widget icon;
final ButtonStyle? buttonStyle;
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final double scale = MediaQuery.textScalerOf(context).textScaleFactor; final double defaultFontSize = buttonStyle?.textStyle?.resolve(const <MaterialState>{})?.fontSize ?? 14.0;
final double gap = scale <= 1 ? 8 : lerpDouble(8, 4, math.min(scale - 1, 1))!; final double scale = clampDouble(MediaQuery.textScalerOf(context).scale(defaultFontSize) / 14.0, 1.0, 2.0) - 1.0;
final double gap = lerpDouble(8, 4, scale)!;
return Row( return Row(
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
children: <Widget>[icon, SizedBox(width: gap), Flexible(child: label)], children: <Widget>[icon, SizedBox(width: gap), Flexible(child: label)],

View File

@ -2,7 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
import 'dart:math' as math;
import 'dart:ui' show lerpDouble; import 'dart:ui' show lerpDouble;
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
@ -479,7 +478,7 @@ class _TextButtonWithIcon extends TextButton {
}) : super( }) : super(
autofocus: autofocus ?? false, autofocus: autofocus ?? false,
clipBehavior: clipBehavior ?? Clip.none, clipBehavior: clipBehavior ?? Clip.none,
child: _TextButtonWithIconChild(icon: icon, label: label), child: _TextButtonWithIconChild(icon: icon, label: label, buttonStyle: style),
); );
@override @override
@ -504,15 +503,18 @@ class _TextButtonWithIconChild extends StatelessWidget {
const _TextButtonWithIconChild({ const _TextButtonWithIconChild({
required this.label, required this.label,
required this.icon, required this.icon,
required this.buttonStyle,
}); });
final Widget label; final Widget label;
final Widget icon; final Widget icon;
final ButtonStyle? buttonStyle;
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final double scale = MediaQuery.textScalerOf(context).textScaleFactor; final double defaultFontSize = buttonStyle?.textStyle?.resolve(const <MaterialState>{})?.fontSize ?? 14.0;
final double gap = scale <= 1 ? 8 : lerpDouble(8, 4, math.min(scale - 1, 1))!; final double scale = clampDouble(MediaQuery.textScalerOf(context).scale(defaultFontSize) / 14.0, 1.0, 2.0) - 1.0;
final double gap = lerpDouble(8, 4, scale)!;
return Row( return Row(
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
children: <Widget>[icon, SizedBox(width: gap), Flexible(child: label)], children: <Widget>[icon, SizedBox(width: gap), Flexible(child: label)],

View File

@ -2348,7 +2348,10 @@ class _TimePickerDialogState extends State<TimePickerDialog> with RestorationMix
// Constrain the textScaleFactor to prevent layout issues. Since only some // Constrain the textScaleFactor to prevent layout issues. Since only some
// parts of the time picker scale up with textScaleFactor, we cap the factor // parts of the time picker scale up with textScaleFactor, we cap the factor
// to 1.1 as that provides enough space to reasonably fit all the content. // to 1.1 as that provides enough space to reasonably fit all the content.
final double textScaleFactor = MediaQuery.textScalerOf(context).clamp(maxScaleFactor: 1.1).textScaleFactor; //
// 14 is a common font size used to compute the effective text scale.
const double fontSizeToScale = 14.0;
final double textScaleFactor = MediaQuery.textScalerOf(context).clamp(maxScaleFactor: 1.1).scale(fontSizeToScale) / fontSizeToScale;
final Size timePickerSize; final Size timePickerSize;
switch (_entryMode.value) { switch (_entryMode.value) {

View File

@ -293,8 +293,9 @@ void main() {
await tester.pumpWidget( await tester.pumpWidget(
createAppWithButtonThatLaunchesActionSheet( createAppWithButtonThatLaunchesActionSheet(
Builder(builder: (BuildContext context) { Builder(builder: (BuildContext context) {
return MediaQuery( return MediaQuery.withClampedTextScaling(
data: MediaQuery.of(context).copyWith(textScaleFactor: 3.0), minScaleFactor: 3.0,
maxScaleFactor: 3.0,
child: CupertinoActionSheet( child: CupertinoActionSheet(
title: const Text('The title'), title: const Text('The title'),
message: const Text('The message.'), message: const Text('The message.'),
@ -361,8 +362,9 @@ void main() {
createAppWithButtonThatLaunchesActionSheet( createAppWithButtonThatLaunchesActionSheet(
Builder(builder: (BuildContext context) { Builder(builder: (BuildContext context) {
screenHeight = MediaQuery.sizeOf(context).height; screenHeight = MediaQuery.sizeOf(context).height;
return MediaQuery( return MediaQuery.withClampedTextScaling(
data: MediaQuery.of(context).copyWith(textScaleFactor: 3.0), minScaleFactor: 3.0,
maxScaleFactor: 3.0,
child: CupertinoActionSheet( child: CupertinoActionSheet(
title: const Text('The title'), title: const Text('The title'),
message: Text('Very long content' * 200), message: Text('Very long content' * 200),
@ -1039,8 +1041,9 @@ void main() {
await tester.pumpWidget( await tester.pumpWidget(
createAppWithButtonThatLaunchesActionSheet( createAppWithButtonThatLaunchesActionSheet(
Builder(builder: (BuildContext context) { Builder(builder: (BuildContext context) {
return MediaQuery( return MediaQuery.withClampedTextScaling(
data: MediaQuery.of(context).copyWith(textScaleFactor: 3.0), minScaleFactor: 3.0,
maxScaleFactor: 3.0,
child: CupertinoActionSheet( child: CupertinoActionSheet(
title: const Text('The title'), title: const Text('The title'),
message: const Text('The message.'), message: const Text('The message.'),

View File

@ -302,8 +302,9 @@ void main() {
await tester.pumpWidget( await tester.pumpWidget(
createAppWithButtonThatLaunchesDialog( createAppWithButtonThatLaunchesDialog(
dialogBuilder: (BuildContext context) { dialogBuilder: (BuildContext context) {
return MediaQuery( return MediaQuery.withClampedTextScaling(
data: MediaQuery.of(context).copyWith(textScaleFactor: 3.0), minScaleFactor: 3.0,
maxScaleFactor: 3.0,
child: CupertinoAlertDialog( child: CupertinoAlertDialog(
title: const Text('The Title'), title: const Text('The Title'),
content: Text('Very long content ' * 20), content: Text('Very long content ' * 20),
@ -405,8 +406,9 @@ void main() {
await tester.pumpWidget( await tester.pumpWidget(
createAppWithButtonThatLaunchesDialog( createAppWithButtonThatLaunchesDialog(
dialogBuilder: (BuildContext context) { dialogBuilder: (BuildContext context) {
return MediaQuery( return MediaQuery.withClampedTextScaling(
data: MediaQuery.of(context).copyWith(textScaleFactor: 3.0), minScaleFactor: 3.0,
maxScaleFactor: 3.0,
child: CupertinoAlertDialog( child: CupertinoAlertDialog(
title: const Text('The title'), title: const Text('The title'),
content: const Text('The content.'), content: const Text('The content.'),
@ -461,14 +463,12 @@ void main() {
}); });
testWidgets('Title Section is empty, Button section is not empty.', (WidgetTester tester) async { testWidgets('Title Section is empty, Button section is not empty.', (WidgetTester tester) async {
const double textScaleFactor = 1.0;
final ScrollController actionScrollController = ScrollController(); final ScrollController actionScrollController = ScrollController();
addTearDown(actionScrollController.dispose); addTearDown(actionScrollController.dispose);
await tester.pumpWidget( await tester.pumpWidget(
createAppWithButtonThatLaunchesDialog( createAppWithButtonThatLaunchesDialog(
dialogBuilder: (BuildContext context) { dialogBuilder: (BuildContext context) {
return MediaQuery( return MediaQuery.withNoTextScaling(
data: MediaQuery.of(context).copyWith(textScaleFactor: textScaleFactor),
child: CupertinoAlertDialog( child: CupertinoAlertDialog(
actions: const <Widget>[ actions: const <Widget>[
CupertinoDialogAction( CupertinoDialogAction(
@ -515,14 +515,12 @@ void main() {
}); });
testWidgets('Button section is empty, Title section is not empty.', (WidgetTester tester) async { testWidgets('Button section is empty, Title section is not empty.', (WidgetTester tester) async {
const double textScaleFactor = 1.0;
final ScrollController scrollController = ScrollController(); final ScrollController scrollController = ScrollController();
addTearDown(scrollController.dispose); addTearDown(scrollController.dispose);
await tester.pumpWidget( await tester.pumpWidget(
createAppWithButtonThatLaunchesDialog( createAppWithButtonThatLaunchesDialog(
dialogBuilder: (BuildContext context) { dialogBuilder: (BuildContext context) {
return MediaQuery( return MediaQuery.withNoTextScaling(
data: MediaQuery.of(context).copyWith(textScaleFactor: textScaleFactor),
child: CupertinoAlertDialog( child: CupertinoAlertDialog(
title: const Text('The title'), title: const Text('The title'),
content: const Text('The content.'), content: const Text('The content.'),
@ -715,8 +713,9 @@ void main() {
await tester.pumpWidget( await tester.pumpWidget(
createAppWithButtonThatLaunchesDialog( createAppWithButtonThatLaunchesDialog(
dialogBuilder: (BuildContext context) { dialogBuilder: (BuildContext context) {
return MediaQuery( return MediaQuery.withClampedTextScaling(
data: MediaQuery.of(context).copyWith(textScaleFactor: 3.0), minScaleFactor: 3.0,
maxScaleFactor: 3.0,
child: CupertinoAlertDialog( child: CupertinoAlertDialog(
title: const Text('The Title'), title: const Text('The Title'),
content: Text('The message\n' * 20), content: Text('The message\n' * 20),
@ -1193,8 +1192,9 @@ void main() {
createAppWithButtonThatLaunchesDialog( createAppWithButtonThatLaunchesDialog(
useMaterial3: false, useMaterial3: false,
dialogBuilder: (BuildContext context) { dialogBuilder: (BuildContext context) {
return MediaQuery( return MediaQuery.withClampedTextScaling(
data: MediaQuery.of(context).copyWith(textScaleFactor: 3.0), minScaleFactor: 3.0,
maxScaleFactor: 3.0,
child: const RepaintBoundary( child: const RepaintBoundary(
child: CupertinoAlertDialog( child: CupertinoAlertDialog(
title: Text('Title'), title: Text('Title'),
@ -1224,8 +1224,9 @@ void main() {
createAppWithButtonThatLaunchesDialog( createAppWithButtonThatLaunchesDialog(
useMaterial3: true, useMaterial3: true,
dialogBuilder: (BuildContext context) { dialogBuilder: (BuildContext context) {
return MediaQuery( return MediaQuery.withClampedTextScaling(
data: MediaQuery.of(context).copyWith(textScaleFactor: 3.0), minScaleFactor: 3.0,
maxScaleFactor: 3.0,
child: const RepaintBoundary( child: const RepaintBoundary(
child: CupertinoAlertDialog( child: CupertinoAlertDialog(
title: Text('Title'), title: Text('Title'),
@ -1322,14 +1323,12 @@ void main() {
testWidgets('Conflicting scrollbars are not applied by ScrollBehavior to CupertinoAlertDialog', (WidgetTester tester) async { testWidgets('Conflicting scrollbars are not applied by ScrollBehavior to CupertinoAlertDialog', (WidgetTester tester) async {
// Regression test for https://github.com/flutter/flutter/issues/83819 // Regression test for https://github.com/flutter/flutter/issues/83819
const double textScaleFactor = 1.0;
final ScrollController actionScrollController = ScrollController(); final ScrollController actionScrollController = ScrollController();
addTearDown(actionScrollController.dispose); addTearDown(actionScrollController.dispose);
await tester.pumpWidget( await tester.pumpWidget(
createAppWithButtonThatLaunchesDialog( createAppWithButtonThatLaunchesDialog(
dialogBuilder: (BuildContext context) { dialogBuilder: (BuildContext context) {
return MediaQuery( return MediaQuery.withNoTextScaling(
data: MediaQuery.of(context).copyWith(textScaleFactor: textScaleFactor),
child: CupertinoAlertDialog( child: CupertinoAlertDialog(
title: const Text('Test Title'), title: const Text('Test Title'),
content: const Text('Test Content'), content: const Text('Test Content'),
@ -1507,8 +1506,9 @@ void main() {
await tester.pumpWidget( await tester.pumpWidget(
createAppWithButtonThatLaunchesDialog( createAppWithButtonThatLaunchesDialog(
dialogBuilder: (BuildContext context) { dialogBuilder: (BuildContext context) {
return MediaQuery( return MediaQuery.withClampedTextScaling(
data: MediaQuery.of(context).copyWith(textScaleFactor: 3.0), minScaleFactor: 3.0,
maxScaleFactor: 3.0,
child: RepaintBoundary( child: RepaintBoundary(
child: CupertinoAlertDialog( child: CupertinoAlertDialog(
title: const Text('Title'), title: const Text('Title'),

View File

@ -287,8 +287,9 @@ void main() {
await tester.pumpWidget( await tester.pumpWidget(
MaterialApp( MaterialApp(
home: Builder(builder: (BuildContext context) { home: Builder(builder: (BuildContext context) {
return MediaQuery( return MediaQuery.withClampedTextScaling(
data: MediaQuery.of(context).copyWith(textScaleFactor: 99), minScaleFactor: 99,
maxScaleFactor: 99,
child: CupertinoTabScaffold( child: CupertinoTabScaffold(
tabBar: CupertinoTabBar( tabBar: CupertinoTabBar(
items: List<BottomNavigationBarItem>.generate( items: List<BottomNavigationBarItem>.generate(

View File

@ -20,14 +20,14 @@ Future<void> startTransitionBetween(
String? toTitle, String? toTitle,
TextDirection textDirection = TextDirection.ltr, TextDirection textDirection = TextDirection.ltr,
CupertinoThemeData? theme, CupertinoThemeData? theme,
double textScale = 1.0, TextScaler textScaler = TextScaler.noScaling,
}) async { }) async {
await tester.pumpWidget( await tester.pumpWidget(
CupertinoApp( CupertinoApp(
theme: theme, theme: theme,
builder: (BuildContext context, Widget? navigator) { builder: (BuildContext context, Widget? navigator) {
return MediaQuery( return MediaQuery(
data: MediaQuery.of(context).copyWith(textScaleFactor: textScale), data: MediaQuery.of(context).copyWith(textScaler: textScaler),
child: Directionality( child: Directionality(
textDirection: textDirection, textDirection: textDirection,
child: navigator!, child: navigator!,
@ -1393,11 +1393,13 @@ void main() {
}); });
testWidgets('textScaleFactor is set to 1.0 on transition', (WidgetTester tester) async { testWidgets('textScaleFactor is set to 1.0 on transition', (WidgetTester tester) async {
await startTransitionBetween(tester, fromTitle: 'Page 1', textScale: 99); await startTransitionBetween(tester, fromTitle: 'Page 1', textScaler: const TextScaler.linear(99));
await tester.pump(const Duration(milliseconds: 50)); await tester.pump(const Duration(milliseconds: 50));
expect(tester.firstWidget<RichText>(flying(tester, find.byType(RichText))).textScaleFactor, 1); final TextScaler scaler = tester.firstWidget<RichText>(flying(tester, find.byType(RichText))).textScaler;
final List<double> fontSizes = List<double>.generate(100, (int index) => index / 3 + 1);
expect(fontSizes.map(scaler.scale), fontSizes);
}); });
testWidgets('Back swipe gesture cancels properly with transition', (WidgetTester tester) async { testWidgets('Back swipe gesture cancels properly with transition', (WidgetTester tester) async {

View File

@ -532,8 +532,9 @@ void main() {
await tester.pumpWidget( await tester.pumpWidget(
CupertinoApp( CupertinoApp(
home: Builder(builder: (BuildContext context) { home: Builder(builder: (BuildContext context) {
return MediaQuery( return MediaQuery.withClampedTextScaling(
data: MediaQuery.of(context).copyWith(textScaleFactor: 99), minScaleFactor: 99,
maxScaleFactor: 99,
child: const CupertinoPageScaffold( child: const CupertinoPageScaffold(
navigationBar: CupertinoNavigationBar( navigationBar: CupertinoNavigationBar(
middle: Text('middle'), middle: Text('middle'),

View File

@ -9,7 +9,7 @@ import 'package:flutter_test/flutter_test.dart';
Widget wrapForChip({ Widget wrapForChip({
required Widget child, required Widget child,
TextDirection textDirection = TextDirection.ltr, TextDirection textDirection = TextDirection.ltr,
double textScaleFactor = 1.0, TextScaler textScaler = TextScaler.noScaling,
Brightness brightness = Brightness.light, Brightness brightness = Brightness.light,
}) { }) {
return MaterialApp( return MaterialApp(
@ -17,7 +17,7 @@ Widget wrapForChip({
home: Directionality( home: Directionality(
textDirection: textDirection, textDirection: textDirection,
child: MediaQuery( child: MediaQuery(
data: MediaQueryData(textScaleFactor: textScaleFactor), data: MediaQueryData(textScaler: textScaler),
child: Material(child: child), child: Material(child: child),
), ),
), ),

View File

@ -3119,8 +3119,9 @@ void main() {
theme: ThemeData(textTheme: Typography.englishLike2014), theme: ThemeData(textTheme: Typography.englishLike2014),
home: Builder( home: Builder(
builder: (BuildContext context) { builder: (BuildContext context) {
return MediaQuery( return MediaQuery.withClampedTextScaling(
data: MediaQuery.of(context).copyWith(textScaleFactor: textScaleFactor), minScaleFactor: textScaleFactor,
maxScaleFactor: textScaleFactor,
child: Scaffold( child: Scaffold(
appBar: AppBar( appBar: AppBar(
centerTitle: false, centerTitle: false,
@ -3166,8 +3167,9 @@ void main() {
return Scaffold( return Scaffold(
appBar: AppBar( appBar: AppBar(
centerTitle: centerTitle, centerTitle: centerTitle,
title: MediaQuery( title: MediaQuery.withClampedTextScaling(
data: MediaQuery.of(context).copyWith(textScaleFactor: textScaleFactor), minScaleFactor: textScaleFactor,
maxScaleFactor: textScaleFactor,
child: const Text('Jumbo'), child: const Text('Jumbo'),
), ),
), ),
@ -5170,8 +5172,9 @@ void main() {
Widget buildAppBar({double textScaleFactor = 1.0}) { Widget buildAppBar({double textScaleFactor = 1.0}) {
return MaterialApp( return MaterialApp(
theme: ThemeData(useMaterial3: true), theme: ThemeData(useMaterial3: true),
home: MediaQuery( home: MediaQuery.withClampedTextScaling(
data: MediaQueryData(textScaleFactor: textScaleFactor), minScaleFactor: textScaleFactor,
maxScaleFactor: textScaleFactor,
child: Material( child: Material(
child: CustomScrollView( child: CustomScrollView(
slivers: <Widget>[ slivers: <Widget>[
@ -5211,8 +5214,9 @@ void main() {
Widget buildAppBar({double textScaleFactor = 1.0}) { Widget buildAppBar({double textScaleFactor = 1.0}) {
return MaterialApp( return MaterialApp(
theme: ThemeData(useMaterial3: true), theme: ThemeData(useMaterial3: true),
home: MediaQuery( home: MediaQuery.withClampedTextScaling(
data: MediaQueryData(textScaleFactor: textScaleFactor), minScaleFactor: textScaleFactor,
maxScaleFactor: textScaleFactor,
child: Material( child: Material(
child: CustomScrollView( child: CustomScrollView(
slivers: <Widget>[ slivers: <Widget>[
@ -5249,8 +5253,9 @@ void main() {
Widget buildAppBar({double textScaleFactor = 1.0}) { Widget buildAppBar({double textScaleFactor = 1.0}) {
return MaterialApp( return MaterialApp(
theme: ThemeData(useMaterial3: true), theme: ThemeData(useMaterial3: true),
home: MediaQuery( home: MediaQuery.withClampedTextScaling(
data: MediaQueryData(textScaleFactor: textScaleFactor), minScaleFactor: textScaleFactor,
maxScaleFactor: textScaleFactor,
child: Material( child: Material(
child: CustomScrollView( child: CustomScrollView(
slivers: <Widget>[ slivers: <Widget>[
@ -5290,8 +5295,9 @@ void main() {
Widget buildAppBar({double textScaleFactor = 1.0}) { Widget buildAppBar({double textScaleFactor = 1.0}) {
return MaterialApp( return MaterialApp(
theme: ThemeData(useMaterial3: true), theme: ThemeData(useMaterial3: true),
home: MediaQuery( home: MediaQuery.withClampedTextScaling(
data: MediaQueryData(textScaleFactor: textScaleFactor), minScaleFactor: textScaleFactor,
maxScaleFactor: textScaleFactor,
child: Material( child: Material(
child: CustomScrollView( child: CustomScrollView(
slivers: <Widget>[ slivers: <Widget>[

View File

@ -1518,8 +1518,9 @@ void main() {
expect(shiftingBox.size.height, equals(kBottomNavigationBarHeight)); expect(shiftingBox.size.height, equals(kBottomNavigationBarHeight));
await tester.pumpWidget( await tester.pumpWidget(
MaterialApp( MaterialApp(
home: MediaQuery( home: MediaQuery.withClampedTextScaling(
data: const MediaQueryData(textScaleFactor: 2.0), minScaleFactor: 2.0,
maxScaleFactor: 2.0,
child: Scaffold( child: Scaffold(
bottomNavigationBar: BottomNavigationBar( bottomNavigationBar: BottomNavigationBar(
items: const <BottomNavigationBarItem>[ items: const <BottomNavigationBarItem>[
@ -1591,8 +1592,9 @@ void main() {
await tester.pumpWidget( await tester.pumpWidget(
MaterialApp( MaterialApp(
home: MediaQuery( home: MediaQuery.withClampedTextScaling(
data: const MediaQueryData(textScaleFactor: 2.0), minScaleFactor: 2.0,
maxScaleFactor: 2.0,
child: Scaffold( child: Scaffold(
bottomNavigationBar: BottomNavigationBar( bottomNavigationBar: BottomNavigationBar(
items: const <BottomNavigationBarItem>[ items: const <BottomNavigationBarItem>[
@ -1770,8 +1772,9 @@ void main() {
const String label = 'Foo'; const String label = 'Foo';
Widget buildApp({ required double textScaleFactor }) { Widget buildApp({ required double textScaleFactor }) {
return MediaQuery( return MediaQuery.withClampedTextScaling(
data: MediaQueryData(textScaleFactor: textScaleFactor), minScaleFactor: textScaleFactor,
maxScaleFactor: textScaleFactor,
child: Localizations( child: Localizations(
locale: const Locale('en', 'US'), locale: const Locale('en', 'US'),
delegates: const <LocalizationsDelegate<dynamic>>[ delegates: const <LocalizationsDelegate<dynamic>>[
@ -1827,9 +1830,9 @@ void main() {
testWidgets('Material3 - BottomNavigationBar shows tool tips with text scaling on long press when labels are provided', (WidgetTester tester) async { testWidgets('Material3 - BottomNavigationBar shows tool tips with text scaling on long press when labels are provided', (WidgetTester tester) async {
const String label = 'Foo'; const String label = 'Foo';
Widget buildApp({ required double textScaleFactor }) { Widget buildApp({ required TextScaler textScaler }) {
return MediaQuery( return MediaQuery(
data: MediaQueryData(textScaleFactor: textScaleFactor), data: MediaQueryData(textScaler: textScaler),
child: Localizations( child: Localizations(
locale: const Locale('en', 'US'), locale: const Locale('en', 'US'),
delegates: const <LocalizationsDelegate<dynamic>>[ delegates: const <LocalizationsDelegate<dynamic>>[
@ -1868,14 +1871,14 @@ void main() {
); );
} }
await tester.pumpWidget(buildApp(textScaleFactor: 1.0)); await tester.pumpWidget(buildApp(textScaler: TextScaler.noScaling));
expect(find.text(label), findsOneWidget); expect(find.text(label), findsOneWidget);
await tester.longPress(find.text(label)); await tester.longPress(find.text(label));
expect(find.text(label), findsNWidgets(2)); expect(find.text(label), findsNWidgets(2));
expect(tester.getSize(find.text(label).last).height, equals(20.0)); expect(tester.getSize(find.text(label).last).height, equals(20.0));
await tester.pumpAndSettle(const Duration(seconds: 2)); await tester.pumpAndSettle(const Duration(seconds: 2));
await tester.pumpWidget(buildApp(textScaleFactor: 4.0)); await tester.pumpWidget(buildApp(textScaler: const TextScaler.linear(4.0)));
expect(find.text(label), findsOneWidget); expect(find.text(label), findsOneWidget);
await tester.longPress(find.text(label)); await tester.longPress(find.text(label));
expect(tester.getSize(find.text(label).last).height, equals(80.0)); expect(tester.getSize(find.text(label).last).height, equals(80.0));

View File

@ -76,7 +76,7 @@ double getDeleteDrawerProgress(WidgetTester tester) => getRenderChip(tester)?.de
Widget wrapForChip({ Widget wrapForChip({
required Widget child, required Widget child,
TextDirection textDirection = TextDirection.ltr, TextDirection textDirection = TextDirection.ltr,
double textScaleFactor = 1.0, TextScaler textScaler = TextScaler.noScaling,
ThemeData? theme, ThemeData? theme,
}) { }) {
return MaterialApp( return MaterialApp(
@ -84,7 +84,7 @@ Widget wrapForChip({
home: Directionality( home: Directionality(
textDirection: textDirection, textDirection: textDirection,
child: MediaQuery( child: MediaQuery(
data: MediaQueryData(textScaleFactor: textScaleFactor), data: MediaQueryData(textScaler: textScaler),
child: Material(child: child), child: Material(child: child),
), ),
), ),
@ -836,7 +836,7 @@ void main() {
await tester.pumpWidget( await tester.pumpWidget(
wrapForChip( wrapForChip(
textScaleFactor: 3.0, textScaler: const TextScaler.linear(3.0),
child: const Column( child: const Column(
children: <Widget>[ children: <Widget>[
Chip( Chip(
@ -906,7 +906,7 @@ void main() {
await tester.pumpWidget( await tester.pumpWidget(
wrapForChip( wrapForChip(
textScaleFactor: 3.0, textScaler: const TextScaler.linear(3.0),
child: const Column( child: const Column(
children: <Widget>[ children: <Widget>[
Chip( Chip(

View File

@ -46,7 +46,7 @@ DefaultTextStyle getLabelStyle(WidgetTester tester, String labelText) {
Widget wrapForChip({ Widget wrapForChip({
required Widget child, required Widget child,
TextDirection textDirection = TextDirection.ltr, TextDirection textDirection = TextDirection.ltr,
double textScaleFactor = 1.0, TextScaler textScaler = TextScaler.noScaling,
Brightness brightness = Brightness.light, Brightness brightness = Brightness.light,
bool? useMaterial3, bool? useMaterial3,
}) { }) {
@ -55,7 +55,7 @@ Widget wrapForChip({
home: Directionality( home: Directionality(
textDirection: textDirection, textDirection: textDirection,
child: MediaQuery( child: MediaQuery(
data: MediaQueryData(textScaleFactor: textScaleFactor), data: MediaQueryData(textScaler: textScaler),
child: Material(child: child), child: Material(child: child),
), ),
), ),

View File

@ -171,7 +171,7 @@ void main() {
expect(paragraph.text.style!.color, equals(theme.colorScheme.onPrimaryContainer)); expect(paragraph.text.style!.color, equals(theme.colorScheme.onPrimaryContainer));
}); });
testWidgets('CircleAvatar text does not expand with textScaleFactor', (WidgetTester tester) async { testWidgets('CircleAvatar text does not expand with textScaler', (WidgetTester tester) async {
final Color foregroundColor = Colors.red.shade100; final Color foregroundColor = Colors.red.shade100;
await tester.pumpWidget( await tester.pumpWidget(
wrap( wrap(
@ -188,7 +188,7 @@ void main() {
wrap( wrap(
child: MediaQuery( child: MediaQuery(
data: const MediaQueryData( data: const MediaQueryData(
textScaleFactor: 2.0, textScaler: TextScaler.linear(2.0),
size: Size(111.0, 111.0), size: Size(111.0, 111.0),
devicePixelRatio: 1.1, devicePixelRatio: 1.1,
padding: EdgeInsets.all(11.0), padding: EdgeInsets.all(11.0),
@ -204,7 +204,7 @@ void main() {
expect(data.padding, equals(const EdgeInsets.all(11.0))); expect(data.padding, equals(const EdgeInsets.all(11.0)));
// This should be overridden to 1.0. // This should be overridden to 1.0.
expect(data.textScaleFactor, equals(1.0)); expect(data.textScaler, TextScaler.noScaling);
return const Text('Z'); return const Text('Z');
}, },
), ),

View File

@ -2269,16 +2269,16 @@ void main() {
'three', 'three',
]; ];
String? item = items[0]; String? item = items[0];
late MediaQueryData mediaQuery; late double textScale;
await tester.pumpWidget( await tester.pumpWidget(
StatefulBuilder( StatefulBuilder(
builder: (BuildContext context, StateSetter setState) { builder: (BuildContext context, StateSetter setState) {
return MaterialApp( return MaterialApp(
builder: (BuildContext context, Widget? child) { builder: (BuildContext context, Widget? child) {
mediaQuery = MediaQuery.of(context); textScale = MediaQuery.of(context).textScaler.scale(14) / 14;
return MediaQuery( return MediaQuery(
data: mediaQuery, data: MediaQueryData(textScaler: TextScaler.linear(textScale)),
child: child!, child: child!,
); );
}, },
@ -2292,9 +2292,7 @@ void main() {
onChanged: (String? newItem) { onChanged: (String? newItem) {
setState(() { setState(() {
item = newItem; item = newItem;
mediaQuery = mediaQuery.copyWith( textScale += 0.1;
textScaleFactor: mediaQuery.textScaleFactor + 0.1,
);
}); });
}, },
), ),

View File

@ -18,7 +18,7 @@ import 'feedback_tester.dart';
Widget wrapForChip({ Widget wrapForChip({
required Widget child, required Widget child,
TextDirection textDirection = TextDirection.ltr, TextDirection textDirection = TextDirection.ltr,
double textScaleFactor = 1.0, TextScaler textScaler = TextScaler.noScaling,
Brightness brightness = Brightness.light, Brightness brightness = Brightness.light,
bool? useMaterial3, bool? useMaterial3,
}) { }) {
@ -27,7 +27,7 @@ Widget wrapForChip({
home: Directionality( home: Directionality(
textDirection: textDirection, textDirection: textDirection,
child: MediaQuery( child: MediaQuery(
data: MediaQueryData(textScaleFactor: textScaleFactor), data: MediaQueryData(textScaler: textScaler),
child: Material(child: child), child: Material(child: child),
), ),
), ),

View File

@ -23,8 +23,9 @@ Widget wrapForChip({
theme: ThemeData(brightness: brightness, useMaterial3: useMaterial3), theme: ThemeData(brightness: brightness, useMaterial3: useMaterial3),
home: Directionality( home: Directionality(
textDirection: textDirection, textDirection: textDirection,
child: MediaQuery( child: MediaQuery.withClampedTextScaling(
data: MediaQueryData(textScaleFactor: textScaleFactor), minScaleFactor: textScaleFactor,
maxScaleFactor: textScaleFactor,
child: Material(child: child), child: Material(child: child),
), ),
), ),

View File

@ -59,22 +59,22 @@ void main() {
const double leftPadding = 10.0; const double leftPadding = 10.0;
const double rightPadding = 20.0; const double rightPadding = 20.0;
Widget buildFrame({ bool dense = false, bool isTwoLine = false, bool isThreeLine = false, double textScaleFactor = 1.0, double? subtitleScaleFactor }) { Widget buildFrame({ bool dense = false, bool isTwoLine = false, bool isThreeLine = false, TextScaler textScaler = TextScaler.noScaling, TextScaler? subtitleScaler }) {
hasSubtitle = isTwoLine || isThreeLine; hasSubtitle = isTwoLine || isThreeLine;
subtitleScaleFactor ??= textScaleFactor; subtitleScaler ??= textScaler;
return MaterialApp( return MaterialApp(
theme: ThemeData(useMaterial3: true), theme: ThemeData(useMaterial3: true),
home: MediaQuery( home: MediaQuery(
data: MediaQueryData( data: MediaQueryData(
padding: const EdgeInsets.only(left: leftPadding, right: rightPadding), padding: const EdgeInsets.only(left: leftPadding, right: rightPadding),
textScaleFactor: textScaleFactor, textScaler: textScaler,
), ),
child: Material( child: Material(
child: Center( child: Center(
child: ListTile( child: ListTile(
leading: SizedBox(key: leadingKey, width: 24.0, height: 24.0), leading: SizedBox(key: leadingKey, width: 24.0, height: 24.0),
title: const Text('title'), title: const Text('title'),
subtitle: hasSubtitle ? Text('subtitle', textScaleFactor: subtitleScaleFactor) : null, subtitle: hasSubtitle ? Text('subtitle', textScaler: subtitleScaler) : null,
trailing: SizedBox(key: trailingKey, width: 24.0, height: 24.0), trailing: SizedBox(key: trailingKey, width: 24.0, height: 24.0),
dense: dense, dense: dense,
isThreeLine: isThreeLine, isThreeLine: isThreeLine,
@ -146,12 +146,12 @@ void main() {
testHorizontalGeometry(); testHorizontalGeometry();
testVerticalGeometry(88.0); testVerticalGeometry(88.0);
await tester.pumpWidget(buildFrame(textScaleFactor: 4.0)); await tester.pumpWidget(buildFrame(textScaler: const TextScaler.linear(4.0)));
testChildren(); testChildren();
testHorizontalGeometry(); testHorizontalGeometry();
testVerticalGeometry(112.0); testVerticalGeometry(112.0);
await tester.pumpWidget(buildFrame(isTwoLine: true, textScaleFactor: 4.0)); await tester.pumpWidget(buildFrame(isTwoLine: true, textScaler: const TextScaler.linear(4.0)));
testChildren(); testChildren();
testHorizontalGeometry(); testHorizontalGeometry();
if (!kIsWeb || isCanvasKit) { // https://github.com/flutter/flutter/issues/99933 if (!kIsWeb || isCanvasKit) { // https://github.com/flutter/flutter/issues/99933
@ -159,14 +159,14 @@ void main() {
} }
// Make sure that the height of a large subtitle is taken into account. // Make sure that the height of a large subtitle is taken into account.
await tester.pumpWidget(buildFrame(isTwoLine: true, textScaleFactor: 0.5, subtitleScaleFactor: 4.0)); await tester.pumpWidget(buildFrame(isTwoLine: true, textScaler: const TextScaler.linear(0.5), subtitleScaler: const TextScaler.linear(4.0)));
testChildren(); testChildren();
testHorizontalGeometry(); testHorizontalGeometry();
if (!kIsWeb || isCanvasKit) { // https://github.com/flutter/flutter/issues/99933 if (!kIsWeb || isCanvasKit) { // https://github.com/flutter/flutter/issues/99933
testVerticalGeometry(108.0); testVerticalGeometry(108.0);
} }
await tester.pumpWidget(buildFrame(isThreeLine: true, textScaleFactor: 4.0)); await tester.pumpWidget(buildFrame(isThreeLine: true, textScaler: const TextScaler.linear(4.0)));
testChildren(); testChildren();
testHorizontalGeometry(); testHorizontalGeometry();
if (!kIsWeb || isCanvasKit) { // https://github.com/flutter/flutter/issues/99933 if (!kIsWeb || isCanvasKit) { // https://github.com/flutter/flutter/issues/99933
@ -2499,22 +2499,22 @@ void main() {
const double leftPadding = 10.0; const double leftPadding = 10.0;
const double rightPadding = 20.0; const double rightPadding = 20.0;
Widget buildFrame({ bool dense = false, bool isTwoLine = false, bool isThreeLine = false, double textScaleFactor = 1.0, double? subtitleScaleFactor }) { Widget buildFrame({ bool dense = false, bool isTwoLine = false, bool isThreeLine = false, TextScaler textScaler = TextScaler.noScaling, TextScaler? subtitleScaler }) {
hasSubtitle = isTwoLine || isThreeLine; hasSubtitle = isTwoLine || isThreeLine;
subtitleScaleFactor ??= textScaleFactor; subtitleScaler ??= textScaler;
return MaterialApp( return MaterialApp(
theme: ThemeData(useMaterial3: false), theme: ThemeData(useMaterial3: false),
home: MediaQuery( home: MediaQuery(
data: MediaQueryData( data: MediaQueryData(
padding: const EdgeInsets.only(left: leftPadding, right: rightPadding), padding: const EdgeInsets.only(left: leftPadding, right: rightPadding),
textScaleFactor: textScaleFactor, textScaler: textScaler,
), ),
child: Material( child: Material(
child: Center( child: Center(
child: ListTile( child: ListTile(
leading: SizedBox(key: leadingKey, width: 24.0, height: 24.0), leading: SizedBox(key: leadingKey, width: 24.0, height: 24.0),
title: const Text('title'), title: const Text('title'),
subtitle: hasSubtitle ? Text('subtitle', textScaleFactor: subtitleScaleFactor) : null, subtitle: hasSubtitle ? Text('subtitle', textScaler: subtitleScaler) : null,
trailing: SizedBox(key: trailingKey, width: 24.0, height: 24.0), trailing: SizedBox(key: trailingKey, width: 24.0, height: 24.0),
dense: dense, dense: dense,
isThreeLine: isThreeLine, isThreeLine: isThreeLine,
@ -2601,38 +2601,38 @@ void main() {
testHorizontalGeometry(); testHorizontalGeometry();
testVerticalGeometry(76.0); testVerticalGeometry(76.0);
await tester.pumpWidget(buildFrame(textScaleFactor: 4.0)); await tester.pumpWidget(buildFrame(textScaler: const TextScaler.linear(4.0)));
testChildren(); testChildren();
testHorizontalGeometry(); testHorizontalGeometry();
testVerticalGeometry(72.0); testVerticalGeometry(72.0);
await tester.pumpWidget(buildFrame(dense: true, textScaleFactor: 4.0)); await tester.pumpWidget(buildFrame(dense: true, textScaler: const TextScaler.linear(4.0)));
testChildren(); testChildren();
testHorizontalGeometry(); testHorizontalGeometry();
testVerticalGeometry(72.0); testVerticalGeometry(72.0);
await tester.pumpWidget(buildFrame(isTwoLine: true, textScaleFactor: 4.0)); await tester.pumpWidget(buildFrame(isTwoLine: true, textScaler: const TextScaler.linear(4.0)));
testChildren(); testChildren();
testHorizontalGeometry(); testHorizontalGeometry();
testVerticalGeometry(128.0); testVerticalGeometry(128.0);
// Make sure that the height of a large subtitle is taken into account. // Make sure that the height of a large subtitle is taken into account.
await tester.pumpWidget(buildFrame(isTwoLine: true, textScaleFactor: 0.5, subtitleScaleFactor: 4.0)); await tester.pumpWidget(buildFrame(isTwoLine: true, textScaler: const TextScaler.linear(0.5), subtitleScaler: const TextScaler.linear(4.0)));
testChildren(); testChildren();
testHorizontalGeometry(); testHorizontalGeometry();
testVerticalGeometry(72.0); testVerticalGeometry(72.0);
await tester.pumpWidget(buildFrame(isTwoLine: true, dense: true, textScaleFactor: 4.0)); await tester.pumpWidget(buildFrame(isTwoLine: true, dense: true, textScaler: const TextScaler.linear(4.0)));
testChildren(); testChildren();
testHorizontalGeometry(); testHorizontalGeometry();
testVerticalGeometry(128.0); testVerticalGeometry(128.0);
await tester.pumpWidget(buildFrame(isThreeLine: true, textScaleFactor: 4.0)); await tester.pumpWidget(buildFrame(isThreeLine: true, textScaler: const TextScaler.linear(4.0)));
testChildren(); testChildren();
testHorizontalGeometry(); testHorizontalGeometry();
testVerticalGeometry(128.0); testVerticalGeometry(128.0);
await tester.pumpWidget(buildFrame(isThreeLine: true, dense: true, textScaleFactor: 4.0)); await tester.pumpWidget(buildFrame(isThreeLine: true, dense: true, textScaler: const TextScaler.linear(4.0)));
testChildren(); testChildren();
testHorizontalGeometry(); testHorizontalGeometry();
testVerticalGeometry(128.0); testVerticalGeometry(128.0);

View File

@ -307,9 +307,9 @@ void main() {
testWidgets('Material2 - NavigationBar shows tooltips with text scaling', (WidgetTester tester) async { testWidgets('Material2 - NavigationBar shows tooltips with text scaling', (WidgetTester tester) async {
const String label = 'A'; const String label = 'A';
Widget buildApp({ required double textScaleFactor }) { Widget buildApp({ required TextScaler textScaler }) {
return MediaQuery( return MediaQuery(
data: MediaQueryData(textScaleFactor: textScaleFactor), data: MediaQueryData(textScaler: textScaler),
child: Localizations( child: Localizations(
locale: const Locale('en', 'US'), locale: const Locale('en', 'US'),
delegates: const <LocalizationsDelegate<dynamic>>[ delegates: const <LocalizationsDelegate<dynamic>>[
@ -346,7 +346,7 @@ void main() {
); );
} }
await tester.pumpWidget(buildApp(textScaleFactor: 1.0)); await tester.pumpWidget(buildApp(textScaler: TextScaler.noScaling));
expect(find.text(label), findsOneWidget); expect(find.text(label), findsOneWidget);
await tester.longPress(find.text(label)); await tester.longPress(find.text(label));
expect(find.text(label), findsNWidgets(2)); expect(find.text(label), findsNWidgets(2));
@ -357,7 +357,7 @@ void main() {
// The duration is needed to ensure the tooltip disappears. // The duration is needed to ensure the tooltip disappears.
await tester.pumpAndSettle(const Duration(seconds: 2)); await tester.pumpAndSettle(const Duration(seconds: 2));
await tester.pumpWidget(buildApp(textScaleFactor: 4.0)); await tester.pumpWidget(buildApp(textScaler: const TextScaler.linear(4.0)));
expect(find.text(label), findsOneWidget); expect(find.text(label), findsOneWidget);
await tester.longPress(find.text(label)); await tester.longPress(find.text(label));
expect(tester.getSize(find.text(label).last), Size(defaultTooltipSize.width * 4, defaultTooltipSize.height * 4)); expect(tester.getSize(find.text(label).last), Size(defaultTooltipSize.width * 4, defaultTooltipSize.height * 4));
@ -366,9 +366,9 @@ void main() {
testWidgets('Material3 - NavigationBar shows tooltips with text scaling', (WidgetTester tester) async { testWidgets('Material3 - NavigationBar shows tooltips with text scaling', (WidgetTester tester) async {
const String label = 'A'; const String label = 'A';
Widget buildApp({ required double textScaleFactor }) { Widget buildApp({ required TextScaler textScaler }) {
return MediaQuery( return MediaQuery(
data: MediaQueryData(textScaleFactor: textScaleFactor), data: MediaQueryData(textScaler: textScaler),
child: Localizations( child: Localizations(
locale: const Locale('en', 'US'), locale: const Locale('en', 'US'),
delegates: const <LocalizationsDelegate<dynamic>>[ delegates: const <LocalizationsDelegate<dynamic>>[
@ -405,7 +405,7 @@ void main() {
); );
} }
await tester.pumpWidget(buildApp(textScaleFactor: 1.0)); await tester.pumpWidget(buildApp(textScaler: TextScaler.noScaling));
expect(find.text(label), findsOneWidget); expect(find.text(label), findsOneWidget);
await tester.longPress(find.text(label)); await tester.longPress(find.text(label));
expect(find.text(label), findsNWidgets(2)); expect(find.text(label), findsNWidgets(2));
@ -416,7 +416,7 @@ void main() {
// The duration is needed to ensure the tooltip disappears. // The duration is needed to ensure the tooltip disappears.
await tester.pumpAndSettle(const Duration(seconds: 2)); await tester.pumpAndSettle(const Duration(seconds: 2));
await tester.pumpWidget(buildApp(textScaleFactor: 4.0)); await tester.pumpWidget(buildApp(textScaler: const TextScaler.linear(4.0)));
expect(find.text(label), findsOneWidget); expect(find.text(label), findsOneWidget);
await tester.longPress(find.text(label)); await tester.longPress(find.text(label));
@ -597,10 +597,10 @@ void main() {
testWidgets('Navigation bar does not grow with text scale factor', (WidgetTester tester) async { testWidgets('Navigation bar does not grow with text scale factor', (WidgetTester tester) async {
const int animationMilliseconds = 800; const int animationMilliseconds = 800;
Widget widget({double textScaleFactor = 1}) { Widget widget({ TextScaler textScaler = TextScaler.noScaling }) {
return _buildWidget( return _buildWidget(
MediaQuery( MediaQuery(
data: MediaQueryData(textScaleFactor: textScaleFactor), data: MediaQueryData(textScaler: textScaler),
child: NavigationBar( child: NavigationBar(
animationDuration: const Duration(milliseconds: animationMilliseconds), animationDuration: const Duration(milliseconds: animationMilliseconds),
destinations: const <NavigationDestination>[ destinations: const <NavigationDestination>[
@ -621,7 +621,7 @@ void main() {
await tester.pumpWidget(widget()); await tester.pumpWidget(widget());
final double initialHeight = tester.getSize(find.byType(NavigationBar)).height; final double initialHeight = tester.getSize(find.byType(NavigationBar)).height;
await tester.pumpWidget(widget(textScaleFactor: 2)); await tester.pumpWidget(widget(textScaler: const TextScaler.linear(2)));
final double newHeight = tester.getSize(find.byType(NavigationBar)).height; final double newHeight = tester.getSize(find.byType(NavigationBar)).height;
expect(newHeight, equals(initialHeight)); expect(newHeight, equals(initialHeight));

View File

@ -1088,8 +1088,9 @@ void main() {
data: ThemeData(useMaterial3: false), data: ThemeData(useMaterial3: false),
child: Directionality( child: Directionality(
textDirection: TextDirection.ltr, textDirection: TextDirection.ltr,
child: MediaQuery( child: MediaQuery.withClampedTextScaling(
data: const MediaQueryData(textScaleFactor: 1.25), minScaleFactor: 1.25,
maxScaleFactor: 1.25,
child: Center( child: Center(
child: OutlinedButton( child: OutlinedButton(
style: const ButtonStyle( style: const ButtonStyle(
@ -1116,8 +1117,9 @@ void main() {
data: ThemeData(useMaterial3: false), data: ThemeData(useMaterial3: false),
child: Directionality( child: Directionality(
textDirection: TextDirection.ltr, textDirection: TextDirection.ltr,
child: MediaQuery( child: MediaQuery.withClampedTextScaling(
data: const MediaQueryData(textScaleFactor: 3.0), minScaleFactor: 3.0,
maxScaleFactor: 3.0,
child: Center( child: Center(
child: OutlinedButton( child: OutlinedButton(
onPressed: () {}, onPressed: () {},

View File

@ -537,10 +537,9 @@ void main() {
testWidgets('PaginatedDataTable with large text', (WidgetTester tester) async { testWidgets('PaginatedDataTable with large text', (WidgetTester tester) async {
await tester.pumpWidget(MaterialApp( await tester.pumpWidget(MaterialApp(
home: MediaQuery( home: MediaQuery.withClampedTextScaling(
data: const MediaQueryData( minScaleFactor: 20.0,
textScaleFactor: 20.0, maxScaleFactor: 20.0,
),
child: PaginatedDataTable( child: PaginatedDataTable(
header: const Text('HEADER'), header: const Text('HEADER'),
source: source, source: source,

View File

@ -1657,7 +1657,7 @@ void main() {
child: StatefulBuilder( child: StatefulBuilder(
builder: (BuildContext context, StateSetter setState) { builder: (BuildContext context, StateSetter setState) {
return MediaQuery( return MediaQuery(
data: const MediaQueryData(textScaleFactor: 2.0), data: const MediaQueryData(textScaler: TextScaler.linear(2)),
child: Material( child: Material(
child: Center( child: Center(
child: Theme( child: Theme(

View File

@ -834,7 +834,7 @@ void main() {
child: StatefulBuilder( child: StatefulBuilder(
builder: (BuildContext context, StateSetter setState) { builder: (BuildContext context, StateSetter setState) {
return MediaQuery( return MediaQuery(
data: MediaQueryData(textScaleFactor: textScaleFactor), data: MediaQueryData(textScaler: TextScaler.linear(textScaleFactor)),
child: Material( child: Material(
child: Theme( child: Theme(
data: Theme.of(context).copyWith( data: Theme.of(context).copyWith(

View File

@ -908,13 +908,13 @@ void main() {
showValueIndicator: ShowValueIndicator.always, showValueIndicator: ShowValueIndicator.always,
valueIndicatorShape: const PaddleSliderValueIndicatorShape(), valueIndicatorShape: const PaddleSliderValueIndicatorShape(),
); );
Widget buildApp(String value, { double sliderValue = 0.5, double textScale = 1.0 }) { Widget buildApp(String value, { double sliderValue = 0.5, TextScaler textScaler = TextScaler.noScaling }) {
return MaterialApp( return MaterialApp(
theme: theme, theme: theme,
home: Directionality( home: Directionality(
textDirection: TextDirection.ltr, textDirection: TextDirection.ltr,
child: MediaQuery( child: MediaQuery(
data: MediaQueryData(textScaleFactor: textScale), data: MediaQueryData(textScaler: textScaler),
child: Material( child: Material(
child: Row( child: Row(
children: <Widget>[ children: <Widget>[
@ -1025,7 +1025,7 @@ void main() {
await gesture.up(); await gesture.up();
// Test that the neck stretches when the text scale gets smaller. // Test that the neck stretches when the text scale gets smaller.
await tester.pumpWidget(buildApp('1000000', sliderValue: 0.0, textScale: 0.5)); await tester.pumpWidget(buildApp('1000000', sliderValue: 0.0, textScaler: const TextScaler.linear(0.5)));
center = tester.getCenter(find.byType(Slider)); center = tester.getCenter(find.byType(Slider));
gesture = await tester.startGesture(center); gesture = await tester.startGesture(center);
// Wait for value indicator animation to finish. // Wait for value indicator animation to finish.
@ -1051,7 +1051,7 @@ void main() {
await gesture.up(); await gesture.up();
// Test that the neck shrinks when the text scale gets larger. // Test that the neck shrinks when the text scale gets larger.
await tester.pumpWidget(buildApp('1000000', sliderValue: 0.0, textScale: 2.5)); await tester.pumpWidget(buildApp('1000000', sliderValue: 0.0, textScaler: const TextScaler.linear(2.5)));
center = tester.getCenter(find.byType(Slider)); center = tester.getCenter(find.byType(Slider));
gesture = await tester.startGesture(center); gesture = await tester.startGesture(center);
// Wait for value indicator animation to finish. // Wait for value indicator animation to finish.
@ -1092,13 +1092,13 @@ void main() {
showValueIndicator: ShowValueIndicator.always, showValueIndicator: ShowValueIndicator.always,
valueIndicatorShape: const PaddleSliderValueIndicatorShape(), valueIndicatorShape: const PaddleSliderValueIndicatorShape(),
); );
Widget buildApp(String value, { double sliderValue = 0.5, double textScale = 1.0 }) { Widget buildApp(String value, { double sliderValue = 0.5, TextScaler textScaler = TextScaler.noScaling }) {
return MaterialApp( return MaterialApp(
theme: theme, theme: theme,
home: Directionality( home: Directionality(
textDirection: TextDirection.ltr, textDirection: TextDirection.ltr,
child: MediaQuery( child: MediaQuery(
data: MediaQueryData(textScaleFactor: textScale), data: MediaQueryData(textScaler: textScaler),
child: Material( child: Material(
child: Row( child: Row(
children: <Widget>[ children: <Widget>[
@ -1209,7 +1209,7 @@ void main() {
await gesture.up(); await gesture.up();
// Test that the neck stretches when the text scale gets smaller. // Test that the neck stretches when the text scale gets smaller.
await tester.pumpWidget(buildApp('1000000', sliderValue: 0.0, textScale: 0.5)); await tester.pumpWidget(buildApp('1000000', sliderValue: 0.0, textScaler: const TextScaler.linear(0.5)));
center = tester.getCenter(find.byType(Slider)); center = tester.getCenter(find.byType(Slider));
gesture = await tester.startGesture(center); gesture = await tester.startGesture(center);
// Wait for value indicator animation to finish. // Wait for value indicator animation to finish.
@ -1235,7 +1235,7 @@ void main() {
await gesture.up(); await gesture.up();
// Test that the neck shrinks when the text scale gets larger. // Test that the neck shrinks when the text scale gets larger.
await tester.pumpWidget(buildApp('1000000', sliderValue: 0.0, textScale: 2.5)); await tester.pumpWidget(buildApp('1000000', sliderValue: 0.0, textScaler: const TextScaler.linear(2.5)));
center = tester.getCenter(find.byType(Slider)); center = tester.getCenter(find.byType(Slider));
gesture = await tester.startGesture(center); gesture = await tester.startGesture(center);
// Wait for value indicator animation to finish. // Wait for value indicator animation to finish.
@ -2040,13 +2040,13 @@ void main() {
useMaterial3: true, useMaterial3: true,
platform: TargetPlatform.android, platform: TargetPlatform.android,
); );
Widget buildApp(String value, { double sliderValue = 0.5, double textScale = 1.0 }) { Widget buildApp(String value, { double sliderValue = 0.5, TextScaler textScaler = TextScaler.noScaling }) {
return MaterialApp( return MaterialApp(
theme: theme, theme: theme,
home: Directionality( home: Directionality(
textDirection: TextDirection.ltr, textDirection: TextDirection.ltr,
child: MediaQuery( child: MediaQuery(
data: MediaQueryData(textScaleFactor: textScale), data: MediaQueryData(textScaler: textScaler),
child: Material( child: Material(
child: Row( child: Row(
children: <Widget>[ children: <Widget>[
@ -2596,13 +2596,13 @@ void main() {
useMaterial3: false, useMaterial3: false,
platform: TargetPlatform.android, platform: TargetPlatform.android,
); );
Widget buildApp(String value, { double sliderValue = 0.5, double textScale = 1.0 }) { Widget buildApp(String value, { double sliderValue = 0.5, TextScaler textScaler = TextScaler.noScaling }) {
return MaterialApp( return MaterialApp(
theme: theme, theme: theme,
home: Directionality( home: Directionality(
textDirection: TextDirection.ltr, textDirection: TextDirection.ltr,
child: MediaQuery( child: MediaQuery(
data: MediaQueryData(textScaleFactor: textScale), data: MediaQueryData(textScaler: textScaler),
child: Material( child: Material(
child: Row( child: Row(
children: <Widget>[ children: <Widget>[

View File

@ -615,8 +615,9 @@ void main() {
data: ThemeData(useMaterial3: false), data: ThemeData(useMaterial3: false),
child: Directionality( child: Directionality(
textDirection: TextDirection.ltr, textDirection: TextDirection.ltr,
child: MediaQuery( child: MediaQuery.withClampedTextScaling(
data: const MediaQueryData(textScaleFactor: 1.25), minScaleFactor: 1.25,
maxScaleFactor: 1.25,
child: Center( child: Center(
child: TextButton( child: TextButton(
onPressed: () { }, onPressed: () { },
@ -639,8 +640,9 @@ void main() {
data: ThemeData(useMaterial3: false), data: ThemeData(useMaterial3: false),
child: Directionality( child: Directionality(
textDirection: TextDirection.ltr, textDirection: TextDirection.ltr,
child: MediaQuery( child: MediaQuery.withClampedTextScaling(
data: const MediaQueryData(textScaleFactor: 3.0), minScaleFactor: 3.0,
maxScaleFactor: 3.0,
child: Center( child: Center(
child: TextButton( child: TextButton(
onPressed: () { }, onPressed: () { },

View File

@ -8854,7 +8854,7 @@ void main() {
theme: ThemeData(useMaterial3: false), theme: ThemeData(useMaterial3: false),
home: Scaffold( home: Scaffold(
body: MediaQuery( body: MediaQuery(
data: const MediaQueryData(textScaleFactor: 4.0), data: const MediaQueryData(textScaler: TextScaler.linear(4.0)),
child: Center( child: Center(
child: TextField( child: TextField(
decoration: const InputDecoration(labelText: 'Label', border: UnderlineInputBorder()), decoration: const InputDecoration(labelText: 'Label', border: UnderlineInputBorder()),

View File

@ -1083,7 +1083,7 @@ void main() {
// Verify that the time display is not affected by text scale. // Verify that the time display is not affected by text scale.
await mediaQueryBoilerplate( await mediaQueryBoilerplate(
tester, tester,
textScaleFactor: 2, textScaler: const TextScaler.linear(2),
initialTime: const TimeOfDay(hour: 7, minute: 41), initialTime: const TimeOfDay(hour: 7, minute: 41),
materialType: materialType, materialType: materialType,
); );
@ -1098,7 +1098,7 @@ void main() {
// Verify that text scale for AM/PM is at most 2x. // Verify that text scale for AM/PM is at most 2x.
await mediaQueryBoilerplate( await mediaQueryBoilerplate(
tester, tester,
textScaleFactor: 3, textScaler: const TextScaler.linear(3),
initialTime: const TimeOfDay(hour: 7, minute: 41), initialTime: const TimeOfDay(hour: 7, minute: 41),
materialType: materialType, materialType: materialType,
); );
@ -1996,7 +1996,7 @@ Future<void> mediaQueryBoilerplate(
WidgetTester tester, { WidgetTester tester, {
bool alwaysUse24HourFormat = false, bool alwaysUse24HourFormat = false,
TimeOfDay initialTime = const TimeOfDay(hour: 7, minute: 0), TimeOfDay initialTime = const TimeOfDay(hour: 7, minute: 0),
double textScaleFactor = 1, TextScaler textScaler = TextScaler.noScaling,
TimePickerEntryMode entryMode = TimePickerEntryMode.dial, TimePickerEntryMode entryMode = TimePickerEntryMode.dial,
String? helpText, String? helpText,
String? hourLabelText, String? hourLabelText,
@ -2020,7 +2020,7 @@ Future<void> mediaQueryBoilerplate(
child: MediaQuery( child: MediaQuery(
data: MediaQueryData( data: MediaQueryData(
alwaysUse24HourFormat: alwaysUse24HourFormat, alwaysUse24HourFormat: alwaysUse24HourFormat,
textScaleFactor: textScaleFactor, textScaler: textScaler,
accessibleNavigation: accessibleNavigation, accessibleNavigation: accessibleNavigation,
size: tester.view.physicalSize / tester.view.devicePixelRatio, size: tester.view.physicalSize / tester.view.devicePixelRatio,
), ),

View File

@ -1930,12 +1930,12 @@ void main() {
semantics.dispose(); semantics.dispose();
}); });
testWidgets('Material2 - Tooltip text scales with textScaleFactor', (WidgetTester tester) async { testWidgets('Material2 - Tooltip text scales with textScaler', (WidgetTester tester) async {
Widget buildApp(String text, { required double textScaleFactor }) { Widget buildApp(String text, { required TextScaler textScaler }) {
return MaterialApp( return MaterialApp(
theme: ThemeData(useMaterial3: false), theme: ThemeData(useMaterial3: false),
home: MediaQuery( home: MediaQuery(
data: MediaQueryData(textScaleFactor: textScaleFactor), data: MediaQueryData(textScaler: textScaler),
child: Directionality( child: Directionality(
textDirection: TextDirection.ltr, textDirection: TextDirection.ltr,
child: Navigator( child: Navigator(
@ -1961,7 +1961,7 @@ void main() {
); );
} }
await tester.pumpWidget(buildApp(tooltipText, textScaleFactor: 1.0)); await tester.pumpWidget(buildApp(tooltipText, textScaler: TextScaler.noScaling));
await tester.longPress(find.byType(Tooltip)); await tester.longPress(find.byType(Tooltip));
expect(find.text(tooltipText), findsOneWidget); expect(find.text(tooltipText), findsOneWidget);
expect(tester.getSize(find.text(tooltipText)), equals(const Size(42.0, 14.0))); expect(tester.getSize(find.text(tooltipText)), equals(const Size(42.0, 14.0)));
@ -1970,7 +1970,7 @@ void main() {
); );
expect(tip.size.height, equals(32.0)); expect(tip.size.height, equals(32.0));
await tester.pumpWidget(buildApp(tooltipText, textScaleFactor: 4.0)); await tester.pumpWidget(buildApp(tooltipText, textScaler: const TextScaler.linear(4.0)));
await tester.longPress(find.byType(Tooltip)); await tester.longPress(find.byType(Tooltip));
expect(find.text(tooltipText), findsOneWidget); expect(find.text(tooltipText), findsOneWidget);
expect(tester.getSize(find.text(tooltipText)), equals(const Size(168.0, 56.0))); expect(tester.getSize(find.text(tooltipText)), equals(const Size(168.0, 56.0)));
@ -1981,10 +1981,10 @@ void main() {
}); });
testWidgets('Material3 - Tooltip text scales with textScaleFactor', (WidgetTester tester) async { testWidgets('Material3 - Tooltip text scales with textScaleFactor', (WidgetTester tester) async {
Widget buildApp(String text, { required double textScaleFactor }) { Widget buildApp(String text, { required TextScaler textScaler }) {
return MaterialApp( return MaterialApp(
home: MediaQuery( home: MediaQuery(
data: MediaQueryData(textScaleFactor: textScaleFactor), data: MediaQueryData(textScaler: textScaler),
child: Navigator( child: Navigator(
onGenerateRoute: (RouteSettings settings) { onGenerateRoute: (RouteSettings settings) {
return MaterialPageRoute<void>( return MaterialPageRoute<void>(
@ -2007,7 +2007,7 @@ void main() {
); );
} }
await tester.pumpWidget(buildApp(tooltipText, textScaleFactor: 1.0)); await tester.pumpWidget(buildApp(tooltipText, textScaler: TextScaler.noScaling));
await tester.longPress(find.byType(Tooltip)); await tester.longPress(find.byType(Tooltip));
expect(find.text(tooltipText), findsOneWidget); expect(find.text(tooltipText), findsOneWidget);
expect(tester.getSize(find.text(tooltipText)).width, equals(42.75)); expect(tester.getSize(find.text(tooltipText)).width, equals(42.75));
@ -2017,7 +2017,7 @@ void main() {
); );
expect(tip.size.height, equals(32.0)); expect(tip.size.height, equals(32.0));
await tester.pumpWidget(buildApp(tooltipText, textScaleFactor: 4.0)); await tester.pumpWidget(buildApp(tooltipText, textScaler: const TextScaler.linear(4.0)));
await tester.longPress(find.byType(Tooltip)); await tester.longPress(find.byType(Tooltip));
expect(find.text(tooltipText), findsOneWidget); expect(find.text(tooltipText), findsOneWidget);
expect(tester.getSize(find.text(tooltipText)).width, equals(168.75)); expect(tester.getSize(find.text(tooltipText)).width, equals(168.75));

View File

@ -410,8 +410,9 @@ Future<void> _buildValueIndicatorStaticSlider(
body: Builder( body: Builder(
builder: (BuildContext context) { builder: (BuildContext context) {
return Center( return Center(
child: MediaQuery( child: MediaQuery.withClampedTextScaling(
data: MediaQueryData(textScaleFactor: textScale), minScaleFactor: textScale,
maxScaleFactor: textScale,
child: SliderTheme( child: SliderTheme(
data: Theme.of(context).sliderTheme.copyWith( data: Theme.of(context).sliderTheme.copyWith(
showValueIndicator: ShowValueIndicator.always, showValueIndicator: ShowValueIndicator.always,

View File

@ -624,13 +624,13 @@ void main() {
); );
await tester.pumpWidget( await tester.pumpWidget(
MediaQuery(data: const MediaQueryData(textScaleFactor: 10), child: widget), MediaQuery(data: const MediaQueryData(textScaler: TextScaler.linear(10)), child: widget),
); );
expect(routeBuildCount, equals(1)); expect(routeBuildCount, equals(1));
await tester.pumpWidget( await tester.pumpWidget(
MediaQuery(data: const MediaQueryData(textScaleFactor: 20), child: widget), MediaQuery(data: const MediaQueryData(textScaler: TextScaler.linear(20)), child: widget),
); );
expect(routeBuildCount, equals(1)); expect(routeBuildCount, equals(1));

View File

@ -164,7 +164,7 @@ void main() {
testWidgets('MediaQueryData.fromView uses platformData if provided', (WidgetTester tester) async { testWidgets('MediaQueryData.fromView uses platformData if provided', (WidgetTester tester) async {
const MediaQueryData platformData = MediaQueryData( const MediaQueryData platformData = MediaQueryData(
textScaleFactor: 1234, textScaler: TextScaler.linear(1234),
platformBrightness: Brightness.dark, platformBrightness: Brightness.dark,
accessibleNavigation: true, accessibleNavigation: true,
invertColors: true, invertColors: true,
@ -231,7 +231,7 @@ void main() {
testWidgets('MediaQuery.fromView injects a new MediaQuery with data from view, preserving platform-specific data', (WidgetTester tester) async { testWidgets('MediaQuery.fromView injects a new MediaQuery with data from view, preserving platform-specific data', (WidgetTester tester) async {
const MediaQueryData platformData = MediaQueryData( const MediaQueryData platformData = MediaQueryData(
textScaleFactor: 1234, textScaler: TextScaler.linear(1234),
platformBrightness: Brightness.dark, platformBrightness: Brightness.dark,
accessibleNavigation: true, accessibleNavigation: true,
invertColors: true, invertColors: true,

View File

@ -14,9 +14,10 @@ import 'semantics_tester.dart';
void main() { void main() {
testWidgets('Text respects media query', (WidgetTester tester) async { testWidgets('Text respects media query', (WidgetTester tester) async {
await tester.pumpWidget(const MediaQuery( await tester.pumpWidget(MediaQuery.withClampedTextScaling(
data: MediaQueryData(textScaleFactor: 1.3), minScaleFactor: 1.3,
child: Center( maxScaleFactor: 1.3,
child: const Center(
child: Text('Hello', textDirection: TextDirection.ltr), child: Text('Hello', textDirection: TextDirection.ltr),
), ),
)); ));