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
EdgeInsetsGeometry? get padding => const EdgeInsets.all(8.0);
/// 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.
/// The label padding of the chip scales with the font size specified in the
/// [labelStyle], and the system font size settings that scale font sizes
/// globally.
///
/// 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
EdgeInsetsGeometry? get labelPadding => 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),
)!;
EdgeInsetsGeometry? get labelPadding {
final double fontSize = labelStyle?.fontSize ?? 14.0;
final double fontSizeRatio = MediaQuery.textScalerOf(context).scale(fontSize) / 14.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
EdgeInsetsGeometry? get padding => const EdgeInsets.all(8.0);
/// 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.
/// The label padding of the chip scales with the font size specified in the
/// [labelStyle], and the system font size settings that scale font sizes
/// globally.
///
/// 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
EdgeInsetsGeometry? get labelPadding => 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),
)!;
EdgeInsetsGeometry? get labelPadding {
final double fontSize = labelStyle?.fontSize ?? 14.0;
final double fontSizeRatio = MediaQuery.textScalerOf(context).scale(fontSize) / 14.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
EdgeInsetsGeometry? get padding => const EdgeInsets.all(8.0);
/// 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.
/// The label padding of the chip scales with the font size specified in the
/// [labelStyle], and the system font size settings that scale font sizes
/// globally.
///
/// 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
EdgeInsetsGeometry? get labelPadding => 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),
)!;
EdgeInsetsGeometry? get labelPadding {
final double fontSize = labelStyle?.fontSize ?? 14.0;
final double fontSizeRatio = MediaQuery.textScalerOf(context).scale(fontSize) / 14.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
EdgeInsetsGeometry? get padding => const EdgeInsets.all(8.0);
/// 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.
/// The label padding of the chip scales with the font size specified in the
/// [labelStyle], and the system font size settings that scale font sizes
/// globally.
///
/// 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
EdgeInsetsGeometry? get labelPadding => 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),
)!;
EdgeInsetsGeometry? get labelPadding {
final double fontSize = labelStyle?.fontSize ?? 14.0;
final double fontSizeRatio = MediaQuery.textScalerOf(context).scale(fontSize) / 14.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) {
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(
EdgeInsets.symmetric(horizontal: math.max(
_kMenuViewPadding,
@ -210,7 +215,7 @@ class _MenuButtonDefaultsM3 extends ButtonStyle {
8 + visualDensity.baseSizeAdjustment.dx,
)),
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
// user has selected.
bool _isInAccessibilityMode(BuildContext context) {
final double? factor = MediaQuery.maybeTextScalerOf(context)?.textScaleFactor;
return factor != null && factor > _kMaxRegularTextScaleFactor;
const double defaultFontSize = 14.0;
final double? scaledFontSize = MediaQuery.maybeTextScalerOf(context)?.scale(defaultFontSize);
return scaledFontSize != null && scaledFontSize > defaultFontSize * _kMaxRegularTextScaleFactor;
}
/// An iOS-style alert dialog.
@ -264,7 +265,8 @@ class _CupertinoAlertDialogState extends State<CupertinoAlertDialog> {
widget.actionScrollController ?? (_backupActionScrollController ??= ScrollController());
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>[
if (widget.title != null || widget.content != null)
@ -278,12 +280,12 @@ class _CupertinoAlertDialogState extends State<CupertinoAlertDialog> {
left: _kDialogEdgePadding,
right: _kDialogEdgePadding,
bottom: widget.content == null ? _kDialogEdgePadding : 1.0,
top: _kDialogEdgePadding * textScaleFactor,
top: _kDialogEdgePadding * effectiveTextScaleFactor,
),
messagePadding: EdgeInsets.only(
left: _kDialogEdgePadding,
right: _kDialogEdgePadding,
bottom: _kDialogEdgePadding * textScaleFactor,
bottom: _kDialogEdgePadding * effectiveTextScaleFactor,
top: widget.title == null ? _kDialogEdgePadding : 1.0,
),
titleTextStyle: _kCupertinoDialogTitleStyle.copyWith(
@ -1653,10 +1655,6 @@ class CupertinoDialogAction extends StatelessWidget {
/// value.
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
// cannot fit at the minimum size, the text content is ellipsized.
//
@ -1665,6 +1663,7 @@ class CupertinoDialogAction extends StatelessWidget {
required BuildContext context,
required TextStyle textStyle,
required Widget content,
required double padding,
}) {
final bool isInAccessibilityMode = _isInAccessibilityMode(context);
final double dialogWidth = isInAccessibilityMode
@ -1675,7 +1674,6 @@ class CupertinoDialogAction extends StatelessWidget {
// buttons. This ratio information is used to automatically scale down action
// button text to fit the available space.
final double fontSizeRatio = MediaQuery.textScalerOf(context).scale(textStyle.fontSize!) / _kDialogMinButtonFontSize;
final double padding = _calculatePadding(context);
return IntrinsicHeight(
child: SizedBox(
@ -1724,8 +1722,7 @@ class CupertinoDialogAction extends StatelessWidget {
isDestructiveAction ? CupertinoColors.systemRed : CupertinoTheme.of(context).primaryColor,
context,
),
);
style = style.merge(textStyle);
).merge(textStyle);
if (isDefaultAction) {
style = style.copyWith(fontWeight: FontWeight.w600);
@ -1734,7 +1731,10 @@ class CupertinoDialogAction extends StatelessWidget {
if (!enabled) {
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
// not the device is in accessibility mode.
// TODO(mattcarroll): The following logic is not entirely correct. It is also
@ -1750,6 +1750,7 @@ class CupertinoDialogAction extends StatelessWidget {
context: context,
textStyle: style,
content: child,
padding: padding,
);
return MouseRegion(
@ -1764,7 +1765,7 @@ class CupertinoDialogAction extends StatelessWidget {
),
child: Container(
alignment: Alignment.center,
padding: EdgeInsets.all(_calculatePadding(context)),
padding: EdgeInsets.all(padding),
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,
// 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
// background color and border radius.

View File

@ -304,16 +304,24 @@ class _ActionChipDefaultsM3 extends ChipThemeData {
@override
EdgeInsetsGeometry? get padding => const EdgeInsets.all(8.0);
/// 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.
/// The label padding of the chip scales with the font size specified in the
/// [labelStyle], and the system font size settings that scale font sizes
/// globally.
///
/// 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
EdgeInsetsGeometry? get labelPadding => 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),
)!;
EdgeInsetsGeometry? get labelPadding {
final double fontSize = labelStyle?.fontSize ?? 14.0;
final double fontSizeRatio = MediaQuery.textScalerOf(context).scale(fontSize) / 14.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

View File

@ -1158,16 +1158,6 @@ class _RawChipState extends State<RawChip> with MaterialStateMixin, TickerProvid
assert(debugCheckHasDirectionality(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 ChipThemeData chipTheme = ChipTheme.of(context);
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.
final TextStyle labelStyle = chipTheme.labelStyle
?? chipDefaults.labelStyle!;
final EdgeInsetsGeometry labelPadding = widget.labelPadding
?? chipTheme.labelPadding
?? chipDefaults.labelPadding
?? defaultLabelPadding;
final IconThemeData? iconTheme = widget.iconTheme
?? chipTheme.iconTheme
?? chipDefaults.iconTheme;
@ -1230,6 +1216,23 @@ class _RawChipState extends State<RawChip> with MaterialStateMixin, TickerProvid
)
: 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(
elevation: isTapping ? pressElevation : elevation,
shadowColor: widget.selected ? selectedShadowColor : shadowColor,
@ -2319,16 +2322,24 @@ class _ChipDefaultsM3 extends ChipThemeData {
@override
EdgeInsetsGeometry? get padding => const EdgeInsets.all(8.0);
/// 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.
/// The label padding of the chip scales with the font size specified in the
/// [labelStyle], and the system font size settings that scale font sizes
/// globally.
///
/// 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
EdgeInsetsGeometry? get labelPadding => 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),
)!;
EdgeInsetsGeometry? get labelPadding {
final double fontSize = labelStyle?.fontSize ?? 14.0;
final double fontSizeRatio = MediaQuery.textScalerOf(context).scale(fontSize) / 14.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

View File

@ -329,16 +329,24 @@ class _ChoiceChipDefaultsM3 extends ChipThemeData {
@override
EdgeInsetsGeometry? get padding => const EdgeInsets.all(8.0);
/// 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.
/// The label padding of the chip scales with the font size specified in the
/// [labelStyle], and the system font size settings that scale font sizes
/// globally.
///
/// 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
EdgeInsetsGeometry? get labelPadding => 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),
)!;
EdgeInsetsGeometry? get labelPadding {
final double fontSize = labelStyle?.fontSize ?? 14.0;
final double fontSizeRatio = MediaQuery.textScalerOf(context).scale(fontSize) / 14.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

View File

@ -659,7 +659,9 @@ class _DatePickerDialogState extends State<DatePickerDialog> with RestorationMix
// Constrain the textScaleFactor to the largest supported value to prevent
// 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 DialogTheme dialogTheme = theme.dialogTheme;
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;
switch (orientation) {
case Orientation.portrait:

View File

@ -718,7 +718,9 @@ class AlertDialog extends StatelessWidget {
// The paddingScaleFactor is used to adjust the padding of Dialog's
// 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);
Widget? iconWidget;
@ -1213,7 +1215,11 @@ class SimpleDialog extends StatelessWidget {
// The paddingScaleFactor is used to adjust the padding of Dialog
// 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);
Widget? titleWidget;
@ -1227,7 +1233,7 @@ class SimpleDialog extends StatelessWidget {
bottom: children == null ? effectiveTitlePadding.bottom * paddingScaleFactor : effectiveTitlePadding.bottom,
),
child: DefaultTextStyle(
style: titleTextStyle ?? DialogTheme.of(context).titleTextStyle ?? theme.textTheme.titleLarge!,
style: defaultTextStyle,
child: Semantics(
// For iOS platform, the focus always lands on the title.
// 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);
// 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.

View File

@ -2,7 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'dart:math' as math;
import 'dart:ui' show lerpDouble;
import 'package:flutter/foundation.dart';
@ -483,7 +482,7 @@ class _ElevatedButtonWithIcon extends ElevatedButton {
}) : super(
autofocus: autofocus ?? false,
clipBehavior: clipBehavior ?? Clip.none,
child: _ElevatedButtonWithIconChild(icon: icon, label: label),
child: _ElevatedButtonWithIconChild(icon: icon, label: label, buttonStyle: style),
);
@override
@ -512,15 +511,17 @@ class _ElevatedButtonWithIcon extends ElevatedButton {
}
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 icon;
final ButtonStyle? buttonStyle;
@override
Widget build(BuildContext context) {
final double scale = MediaQuery.textScalerOf(context).textScaleFactor;
final double gap = scale <= 1 ? 8 : lerpDouble(8, 4, math.min(scale - 1, 1))!;
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;
final double gap = lerpDouble(8, 4, scale)!;
return Row(
mainAxisSize: MainAxisSize.min,
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
// found in the LICENSE file.
import 'dart:math' as math;
import 'dart:ui' show lerpDouble;
import 'package:flutter/foundation.dart';
@ -476,7 +475,7 @@ class _FilledButtonWithIcon extends FilledButton {
}) : super(
autofocus: autofocus ?? false,
clipBehavior: clipBehavior ?? Clip.none,
child: _FilledButtonWithIconChild(icon: icon, label: label)
child: _FilledButtonWithIconChild(icon: icon, label: label, buttonStyle: style),
);
_FilledButtonWithIcon.tonal({
@ -495,7 +494,7 @@ class _FilledButtonWithIcon extends FilledButton {
}) : super.tonal(
autofocus: autofocus ?? false,
clipBehavior: clipBehavior ?? Clip.none,
child: _FilledButtonWithIconChild(icon: icon, label: label)
child: _FilledButtonWithIconChild(icon: icon, label: label, buttonStyle: style),
);
@override
@ -524,17 +523,19 @@ class _FilledButtonWithIcon extends FilledButton {
}
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 icon;
final ButtonStyle? buttonStyle;
@override
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
// 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(
mainAxisSize: MainAxisSize.min,
children: <Widget>[icon, SizedBox(width: gap), Flexible(child: label)],

View File

@ -355,16 +355,24 @@ class _FilterChipDefaultsM3 extends ChipThemeData {
@override
EdgeInsetsGeometry? get padding => const EdgeInsets.all(8.0);
/// 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.
/// The label padding of the chip scales with the font size specified in the
/// [labelStyle], and the system font size settings that scale font sizes
/// globally.
///
/// 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
EdgeInsetsGeometry? get labelPadding => 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),
)!;
EdgeInsetsGeometry? get labelPadding {
final double fontSize = labelStyle?.fontSize ?? 14.0;
final double fontSizeRatio = MediaQuery.textScalerOf(context).scale(fontSize) / 14.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

View File

@ -310,16 +310,24 @@ class _InputChipDefaultsM3 extends ChipThemeData {
@override
EdgeInsetsGeometry? get padding => const EdgeInsets.all(8.0);
/// 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.
/// The label padding of the chip scales with the font size specified in the
/// [labelStyle], and the system font size settings that scale font sizes
/// globally.
///
/// 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
EdgeInsetsGeometry? get labelPadding => 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),
)!;
EdgeInsetsGeometry? get labelPadding {
final double fontSize = labelStyle?.fontSize ?? 14.0;
final double fontSizeRatio = MediaQuery.textScalerOf(context).scale(fontSize) / 14.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

View File

@ -2416,7 +2416,7 @@ class _InputDecoratorState extends State<InputDecorator> with TickerProviderStat
contentPadding = decorationContentPadding ?? EdgeInsets.zero;
} else if (!border.isOutline) {
// 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) {
contentPadding = decorationContentPadding ?? (decorationIsDense
? 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) {
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(
EdgeInsets.symmetric(horizontal: math.max(
_kMenuViewPadding,
@ -3913,7 +3918,7 @@ class _MenuButtonDefaultsM3 extends ButtonStyle {
8 + visualDensity.baseSizeAdjustment.dx,
)),
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
// found in the LICENSE file.
import 'dart:math' as math;
import 'dart:ui' show lerpDouble;
import 'package:flutter/foundation.dart';
@ -414,7 +413,7 @@ class _OutlinedButtonWithIcon extends OutlinedButton {
}) : super(
autofocus: autofocus ?? false,
clipBehavior: clipBehavior ?? Clip.none,
child: _OutlinedButtonWithIconChild(icon: icon, label: label),
child: _OutlinedButtonWithIconChild(icon: icon, label: label, buttonStyle: style),
);
@override
@ -442,15 +441,18 @@ class _OutlinedButtonWithIconChild extends StatelessWidget {
const _OutlinedButtonWithIconChild({
required this.label,
required this.icon,
required this.buttonStyle,
});
final Widget label;
final Widget icon;
final ButtonStyle? buttonStyle;
@override
Widget build(BuildContext context) {
final double scale = MediaQuery.textScalerOf(context).textScaleFactor;
final double gap = scale <= 1 ? 8 : lerpDouble(8, 4, math.min(scale - 1, 1))!;
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;
final double gap = lerpDouble(8, 4, scale)!;
return Row(
mainAxisSize: MainAxisSize.min,
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
// found in the LICENSE file.
import 'dart:math' as math;
import 'dart:ui' show lerpDouble;
import 'package:flutter/foundation.dart';
@ -479,7 +478,7 @@ class _TextButtonWithIcon extends TextButton {
}) : super(
autofocus: autofocus ?? false,
clipBehavior: clipBehavior ?? Clip.none,
child: _TextButtonWithIconChild(icon: icon, label: label),
child: _TextButtonWithIconChild(icon: icon, label: label, buttonStyle: style),
);
@override
@ -504,15 +503,18 @@ class _TextButtonWithIconChild extends StatelessWidget {
const _TextButtonWithIconChild({
required this.label,
required this.icon,
required this.buttonStyle,
});
final Widget label;
final Widget icon;
final ButtonStyle? buttonStyle;
@override
Widget build(BuildContext context) {
final double scale = MediaQuery.textScalerOf(context).textScaleFactor;
final double gap = scale <= 1 ? 8 : lerpDouble(8, 4, math.min(scale - 1, 1))!;
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;
final double gap = lerpDouble(8, 4, scale)!;
return Row(
mainAxisSize: MainAxisSize.min,
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
// 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.
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;
switch (_entryMode.value) {

View File

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

View File

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

View File

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

View File

@ -20,14 +20,14 @@ Future<void> startTransitionBetween(
String? toTitle,
TextDirection textDirection = TextDirection.ltr,
CupertinoThemeData? theme,
double textScale = 1.0,
TextScaler textScaler = TextScaler.noScaling,
}) async {
await tester.pumpWidget(
CupertinoApp(
theme: theme,
builder: (BuildContext context, Widget? navigator) {
return MediaQuery(
data: MediaQuery.of(context).copyWith(textScaleFactor: textScale),
data: MediaQuery.of(context).copyWith(textScaler: textScaler),
child: Directionality(
textDirection: textDirection,
child: navigator!,
@ -1393,11 +1393,13 @@ void main() {
});
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));
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 {

View File

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

View File

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

View File

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

View File

@ -1518,8 +1518,9 @@ void main() {
expect(shiftingBox.size.height, equals(kBottomNavigationBarHeight));
await tester.pumpWidget(
MaterialApp(
home: MediaQuery(
data: const MediaQueryData(textScaleFactor: 2.0),
home: MediaQuery.withClampedTextScaling(
minScaleFactor: 2.0,
maxScaleFactor: 2.0,
child: Scaffold(
bottomNavigationBar: BottomNavigationBar(
items: const <BottomNavigationBarItem>[
@ -1591,8 +1592,9 @@ void main() {
await tester.pumpWidget(
MaterialApp(
home: MediaQuery(
data: const MediaQueryData(textScaleFactor: 2.0),
home: MediaQuery.withClampedTextScaling(
minScaleFactor: 2.0,
maxScaleFactor: 2.0,
child: Scaffold(
bottomNavigationBar: BottomNavigationBar(
items: const <BottomNavigationBarItem>[
@ -1770,8 +1772,9 @@ void main() {
const String label = 'Foo';
Widget buildApp({ required double textScaleFactor }) {
return MediaQuery(
data: MediaQueryData(textScaleFactor: textScaleFactor),
return MediaQuery.withClampedTextScaling(
minScaleFactor: textScaleFactor,
maxScaleFactor: textScaleFactor,
child: Localizations(
locale: const Locale('en', 'US'),
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 {
const String label = 'Foo';
Widget buildApp({ required double textScaleFactor }) {
Widget buildApp({ required TextScaler textScaler }) {
return MediaQuery(
data: MediaQueryData(textScaleFactor: textScaleFactor),
data: MediaQueryData(textScaler: textScaler),
child: Localizations(
locale: const Locale('en', 'US'),
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);
await tester.longPress(find.text(label));
expect(find.text(label), findsNWidgets(2));
expect(tester.getSize(find.text(label).last).height, equals(20.0));
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);
await tester.longPress(find.text(label));
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({
required Widget child,
TextDirection textDirection = TextDirection.ltr,
double textScaleFactor = 1.0,
TextScaler textScaler = TextScaler.noScaling,
ThemeData? theme,
}) {
return MaterialApp(
@ -84,7 +84,7 @@ Widget wrapForChip({
home: Directionality(
textDirection: textDirection,
child: MediaQuery(
data: MediaQueryData(textScaleFactor: textScaleFactor),
data: MediaQueryData(textScaler: textScaler),
child: Material(child: child),
),
),
@ -836,7 +836,7 @@ void main() {
await tester.pumpWidget(
wrapForChip(
textScaleFactor: 3.0,
textScaler: const TextScaler.linear(3.0),
child: const Column(
children: <Widget>[
Chip(
@ -906,7 +906,7 @@ void main() {
await tester.pumpWidget(
wrapForChip(
textScaleFactor: 3.0,
textScaler: const TextScaler.linear(3.0),
child: const Column(
children: <Widget>[
Chip(

View File

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

View File

@ -171,7 +171,7 @@ void main() {
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;
await tester.pumpWidget(
wrap(
@ -188,7 +188,7 @@ void main() {
wrap(
child: MediaQuery(
data: const MediaQueryData(
textScaleFactor: 2.0,
textScaler: TextScaler.linear(2.0),
size: Size(111.0, 111.0),
devicePixelRatio: 1.1,
padding: EdgeInsets.all(11.0),
@ -204,7 +204,7 @@ void main() {
expect(data.padding, equals(const EdgeInsets.all(11.0)));
// This should be overridden to 1.0.
expect(data.textScaleFactor, equals(1.0));
expect(data.textScaler, TextScaler.noScaling);
return const Text('Z');
},
),

View File

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

View File

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

View File

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

View File

@ -59,22 +59,22 @@ void main() {
const double leftPadding = 10.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;
subtitleScaleFactor ??= textScaleFactor;
subtitleScaler ??= textScaler;
return MaterialApp(
theme: ThemeData(useMaterial3: true),
home: MediaQuery(
data: MediaQueryData(
padding: const EdgeInsets.only(left: leftPadding, right: rightPadding),
textScaleFactor: textScaleFactor,
textScaler: textScaler,
),
child: Material(
child: Center(
child: ListTile(
leading: SizedBox(key: leadingKey, width: 24.0, height: 24.0),
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),
dense: dense,
isThreeLine: isThreeLine,
@ -146,12 +146,12 @@ void main() {
testHorizontalGeometry();
testVerticalGeometry(88.0);
await tester.pumpWidget(buildFrame(textScaleFactor: 4.0));
await tester.pumpWidget(buildFrame(textScaler: const TextScaler.linear(4.0)));
testChildren();
testHorizontalGeometry();
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();
testHorizontalGeometry();
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.
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();
testHorizontalGeometry();
if (!kIsWeb || isCanvasKit) { // https://github.com/flutter/flutter/issues/99933
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();
testHorizontalGeometry();
if (!kIsWeb || isCanvasKit) { // https://github.com/flutter/flutter/issues/99933
@ -2499,22 +2499,22 @@ void main() {
const double leftPadding = 10.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;
subtitleScaleFactor ??= textScaleFactor;
subtitleScaler ??= textScaler;
return MaterialApp(
theme: ThemeData(useMaterial3: false),
home: MediaQuery(
data: MediaQueryData(
padding: const EdgeInsets.only(left: leftPadding, right: rightPadding),
textScaleFactor: textScaleFactor,
textScaler: textScaler,
),
child: Material(
child: Center(
child: ListTile(
leading: SizedBox(key: leadingKey, width: 24.0, height: 24.0),
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),
dense: dense,
isThreeLine: isThreeLine,
@ -2601,38 +2601,38 @@ void main() {
testHorizontalGeometry();
testVerticalGeometry(76.0);
await tester.pumpWidget(buildFrame(textScaleFactor: 4.0));
await tester.pumpWidget(buildFrame(textScaler: const TextScaler.linear(4.0)));
testChildren();
testHorizontalGeometry();
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();
testHorizontalGeometry();
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();
testHorizontalGeometry();
testVerticalGeometry(128.0);
// 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();
testHorizontalGeometry();
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();
testHorizontalGeometry();
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();
testHorizontalGeometry();
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();
testHorizontalGeometry();
testVerticalGeometry(128.0);

View File

@ -307,9 +307,9 @@ void main() {
testWidgets('Material2 - NavigationBar shows tooltips with text scaling', (WidgetTester tester) async {
const String label = 'A';
Widget buildApp({ required double textScaleFactor }) {
Widget buildApp({ required TextScaler textScaler }) {
return MediaQuery(
data: MediaQueryData(textScaleFactor: textScaleFactor),
data: MediaQueryData(textScaler: textScaler),
child: Localizations(
locale: const Locale('en', 'US'),
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);
await tester.longPress(find.text(label));
expect(find.text(label), findsNWidgets(2));
@ -357,7 +357,7 @@ void main() {
// The duration is needed to ensure the tooltip disappears.
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);
await tester.longPress(find.text(label));
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 {
const String label = 'A';
Widget buildApp({ required double textScaleFactor }) {
Widget buildApp({ required TextScaler textScaler }) {
return MediaQuery(
data: MediaQueryData(textScaleFactor: textScaleFactor),
data: MediaQueryData(textScaler: textScaler),
child: Localizations(
locale: const Locale('en', 'US'),
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);
await tester.longPress(find.text(label));
expect(find.text(label), findsNWidgets(2));
@ -416,7 +416,7 @@ void main() {
// The duration is needed to ensure the tooltip disappears.
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);
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 {
const int animationMilliseconds = 800;
Widget widget({double textScaleFactor = 1}) {
Widget widget({ TextScaler textScaler = TextScaler.noScaling }) {
return _buildWidget(
MediaQuery(
data: MediaQueryData(textScaleFactor: textScaleFactor),
data: MediaQueryData(textScaler: textScaler),
child: NavigationBar(
animationDuration: const Duration(milliseconds: animationMilliseconds),
destinations: const <NavigationDestination>[
@ -621,7 +621,7 @@ void main() {
await tester.pumpWidget(widget());
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;
expect(newHeight, equals(initialHeight));

View File

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

View File

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

View File

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

View File

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

View File

@ -908,13 +908,13 @@ void main() {
showValueIndicator: ShowValueIndicator.always,
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(
theme: theme,
home: Directionality(
textDirection: TextDirection.ltr,
child: MediaQuery(
data: MediaQueryData(textScaleFactor: textScale),
data: MediaQueryData(textScaler: textScaler),
child: Material(
child: Row(
children: <Widget>[
@ -1025,7 +1025,7 @@ void main() {
await gesture.up();
// 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));
gesture = await tester.startGesture(center);
// Wait for value indicator animation to finish.
@ -1051,7 +1051,7 @@ void main() {
await gesture.up();
// 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));
gesture = await tester.startGesture(center);
// Wait for value indicator animation to finish.
@ -1092,13 +1092,13 @@ void main() {
showValueIndicator: ShowValueIndicator.always,
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(
theme: theme,
home: Directionality(
textDirection: TextDirection.ltr,
child: MediaQuery(
data: MediaQueryData(textScaleFactor: textScale),
data: MediaQueryData(textScaler: textScaler),
child: Material(
child: Row(
children: <Widget>[
@ -1209,7 +1209,7 @@ void main() {
await gesture.up();
// 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));
gesture = await tester.startGesture(center);
// Wait for value indicator animation to finish.
@ -1235,7 +1235,7 @@ void main() {
await gesture.up();
// 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));
gesture = await tester.startGesture(center);
// Wait for value indicator animation to finish.
@ -2040,13 +2040,13 @@ void main() {
useMaterial3: true,
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(
theme: theme,
home: Directionality(
textDirection: TextDirection.ltr,
child: MediaQuery(
data: MediaQueryData(textScaleFactor: textScale),
data: MediaQueryData(textScaler: textScaler),
child: Material(
child: Row(
children: <Widget>[
@ -2596,13 +2596,13 @@ void main() {
useMaterial3: false,
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(
theme: theme,
home: Directionality(
textDirection: TextDirection.ltr,
child: MediaQuery(
data: MediaQueryData(textScaleFactor: textScale),
data: MediaQueryData(textScaler: textScaler),
child: Material(
child: Row(
children: <Widget>[

View File

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

View File

@ -8854,7 +8854,7 @@ void main() {
theme: ThemeData(useMaterial3: false),
home: Scaffold(
body: MediaQuery(
data: const MediaQueryData(textScaleFactor: 4.0),
data: const MediaQueryData(textScaler: TextScaler.linear(4.0)),
child: Center(
child: TextField(
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.
await mediaQueryBoilerplate(
tester,
textScaleFactor: 2,
textScaler: const TextScaler.linear(2),
initialTime: const TimeOfDay(hour: 7, minute: 41),
materialType: materialType,
);
@ -1098,7 +1098,7 @@ void main() {
// Verify that text scale for AM/PM is at most 2x.
await mediaQueryBoilerplate(
tester,
textScaleFactor: 3,
textScaler: const TextScaler.linear(3),
initialTime: const TimeOfDay(hour: 7, minute: 41),
materialType: materialType,
);
@ -1996,7 +1996,7 @@ Future<void> mediaQueryBoilerplate(
WidgetTester tester, {
bool alwaysUse24HourFormat = false,
TimeOfDay initialTime = const TimeOfDay(hour: 7, minute: 0),
double textScaleFactor = 1,
TextScaler textScaler = TextScaler.noScaling,
TimePickerEntryMode entryMode = TimePickerEntryMode.dial,
String? helpText,
String? hourLabelText,
@ -2020,7 +2020,7 @@ Future<void> mediaQueryBoilerplate(
child: MediaQuery(
data: MediaQueryData(
alwaysUse24HourFormat: alwaysUse24HourFormat,
textScaleFactor: textScaleFactor,
textScaler: textScaler,
accessibleNavigation: accessibleNavigation,
size: tester.view.physicalSize / tester.view.devicePixelRatio,
),

View File

@ -1930,12 +1930,12 @@ void main() {
semantics.dispose();
});
testWidgets('Material2 - Tooltip text scales with textScaleFactor', (WidgetTester tester) async {
Widget buildApp(String text, { required double textScaleFactor }) {
testWidgets('Material2 - Tooltip text scales with textScaler', (WidgetTester tester) async {
Widget buildApp(String text, { required TextScaler textScaler }) {
return MaterialApp(
theme: ThemeData(useMaterial3: false),
home: MediaQuery(
data: MediaQueryData(textScaleFactor: textScaleFactor),
data: MediaQueryData(textScaler: textScaler),
child: Directionality(
textDirection: TextDirection.ltr,
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));
expect(find.text(tooltipText), findsOneWidget);
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));
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));
expect(find.text(tooltipText), findsOneWidget);
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 {
Widget buildApp(String text, { required double textScaleFactor }) {
Widget buildApp(String text, { required TextScaler textScaler }) {
return MaterialApp(
home: MediaQuery(
data: MediaQueryData(textScaleFactor: textScaleFactor),
data: MediaQueryData(textScaler: textScaler),
child: Navigator(
onGenerateRoute: (RouteSettings settings) {
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));
expect(find.text(tooltipText), findsOneWidget);
expect(tester.getSize(find.text(tooltipText)).width, equals(42.75));
@ -2017,7 +2017,7 @@ void main() {
);
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));
expect(find.text(tooltipText), findsOneWidget);
expect(tester.getSize(find.text(tooltipText)).width, equals(168.75));

View File

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

View File

@ -624,13 +624,13 @@ void main() {
);
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));
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));

View File

@ -164,7 +164,7 @@ void main() {
testWidgets('MediaQueryData.fromView uses platformData if provided', (WidgetTester tester) async {
const MediaQueryData platformData = MediaQueryData(
textScaleFactor: 1234,
textScaler: TextScaler.linear(1234),
platformBrightness: Brightness.dark,
accessibleNavigation: 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 {
const MediaQueryData platformData = MediaQueryData(
textScaleFactor: 1234,
textScaler: TextScaler.linear(1234),
platformBrightness: Brightness.dark,
accessibleNavigation: true,
invertColors: true,

View File

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