弃用 textScaleFactor,转而使用 TextScaler
摘要
#为了准备采用Android 14 非线性字体缩放功能,Flutter 框架中所有 textScaleFactor
的出现都已弃用,并由 TextScaler
替换。
背景
#许多平台允许用户在系统偏好设置中全局放大或缩小文本内容。过去,缩放策略被捕获为一个名为 textScaleFactor
的单个 double
值,因为文本缩放是成比例的:scaledFontSize = textScaleFactor x unScaledFontSize
。例如,当 textScaleFactor
为 2.0 且开发者指定的字体大小为 14.0 时,实际字体大小为 2.0 x 14.0 = 28.0。
随着Android 14 非线性字体缩放的引入,与较小的文本相比,较大的文本的缩放比例较小,以防止已经很大的文本过度缩放。 “比例”缩放使用的 textScaleFactor
标量值不足以表示这种新的缩放策略。替换 textScaleFactor
为 TextScaler
的 pull request 引入了一个新的类 TextScaler
来替换 textScaleFactor
,以准备此新功能。非线性文本缩放在另一个 pull request 中引入。
变更描述
#引入一个新的接口 TextScaler
,它表示文本缩放策略。
abstract class TextScaler {
double scale(double fontSize);
double get textScaleFactor; // Deprecated.
}
使用 scale
方法缩放字体大小,而不是 textScaleFactor
。textScaleFactor
getter 提供了一个估计的 textScaleFactor
值,它用于向后兼容目的,并且已经被标记为已弃用,将在 Flutter 的未来版本中移除。
新类已替换 double textScaleFactor
(double textScaleFactor
-> TextScaler textScaler
),在以下 API 中
绘图库
#受影响的 API | 错误消息 |
---|---|
InlineSpan.build({ double textScaleFactor = 1.0 }) 参数 | 命名参数 'textScaleFactor' 未定义。 |
TextStyle.getParagraphStyle({ double TextScaleFactor = 1.0 }) 参数 | 命名参数 'textScaleFactor' 未定义。 |
TextStyle.getTextStyle({ double TextScaleFactor = 1.0 }) 参数 | 'textScaleFactor' 已弃用,不应使用。 |
TextPainter({ double TextScaleFactor = 1.0 }) 构造函数参数 | 'textScaleFactor' 已弃用,不应使用。 |
TextPainter.textScaleFactor getter 和 setter | 'textScaleFactor' 已弃用,不应使用。 |
TextPainter.computeWidth({ double TextScaleFactor = 1.0 }) 参数 | 'textScaleFactor' 已弃用,不应使用。 |
TextPainter.computeMaxIntrinsicWidth({ double TextScaleFactor = 1.0 }) 参数 | 'textScaleFactor' 已弃用,不应使用。 |
渲染库
#受影响的 API | 错误消息 |
---|---|
RenderEditable({ double TextScaleFactor = 1.0 }) 构造函数参数 | 'textScaleFactor' 已弃用,不应使用。 |
RenderEditable.textScaleFactor getter 和 setter | 'textScaleFactor' 已弃用,不应使用。 |
RenderParagraph({ double TextScaleFactor = 1.0 }) 构造函数参数 | 'textScaleFactor' 已弃用,不应使用。 |
RenderParagraph.textScaleFactor getter 和 setter | 'textScaleFactor' 已弃用,不应使用。 |
Widgets 库
#受影响的 API | 错误消息 |
---|---|
MediaQueryData({ double TextScaleFactor = 1.0 }) 构造函数参数 | 'textScaleFactor' 已弃用,不应使用。 |
MediaQueryData.textScaleFactor getter | 'textScaleFactor' 已弃用,不应使用。 |
MediaQueryData.copyWith({ double? TextScaleFactor }) 参数 | 'textScaleFactor' 已弃用,不应使用。 |
MediaQuery.maybeTextScaleFactorOf(BuildContext context) 静态方法 | 'maybeTextScaleFactorOf' 已弃用,不应使用。 |
MediaQuery.textScaleFactorOf(BuildContext context) 静态方法 | 'textScaleFactorOf' 已弃用,不应使用。 |
RichText({ double TextScaleFactor = 1.0 }) 构造函数参数 | 'textScaleFactor' 已弃用,不应使用。 |
RichText.textScaleFactor getter | 'textScaleFactor' 已弃用,不应使用。 |
Text({ double? TextScaleFactor = 1.0 }) 构造函数参数 | 'textScaleFactor' 已弃用,不应使用。 |
Text.rich({ double? TextScaleFactor = 1.0 }) 构造函数参数 | 'textScaleFactor' 已弃用,不应使用。 |
Text.textScaleFactor getter | 'textScaleFactor' 已弃用,不应使用。 |
EditableText({ double? TextScaleFactor = 1.0 }) 构造函数参数 | 'textScaleFactor' 已弃用,不应使用。 |
EditableText.textScaleFactor getter | 'textScaleFactor' 已弃用,不应使用。 |
Material 库
#受影响的 API | 错误消息 |
---|---|
SelectableText({ double? TextScaleFactor = 1.0 }) 构造函数参数 | 'textScaleFactor' 已弃用,不应使用。 |
SelectableText.rich({ double? TextScaleFactor = 1.0 }) 构造函数参数 | 'textScaleFactor' 已弃用,不应使用。 |
SelectableText.textScaleFactor getter | 'textScaleFactor' 已弃用,不应使用。 |
迁移指南
#Flutter 框架提供的 Widgets 已经迁移。仅当您使用上表中列出的任何已弃用符号时,才需要迁移。
迁移公开 textScaleFactor
的 API
#之前
abstract class _MyCustomPaintDelegate {
void paint(PaintingContext context, Offset offset, double textScaleFactor) {
}
}
之后
abstract class _MyCustomPaintDelegate {
void paint(PaintingContext context, Offset offset, TextScaler textScaler) {
}
}
迁移使用 textScaleFactor
的代码
#如果您目前没有直接使用 textScaleFactor
,而是将其传递给接收 textScaleFactor
的其他 API,并且接收 API 已经迁移,那么这相对简单
之前
RichText(
textScaleFactor: MediaQuery.textScaleFactorOf(context),
...
)
之后
RichText(
textScaler: MediaQuery.textScalerOf(context),
...
)
如果提供 textScaleFactor
的 API 尚未迁移,请考虑等待迁移后的版本。
如果您希望自己计算缩放后的字体大小,请使用 TextScaler.scale
而不是 *
二元运算符
之前
final scaledFontSize = textStyle.fontSize * MediaQuery.textScaleFactorOf(context);
之后
final scaledFontSize = MediaQuery.textScalerOf(context).scale(textStyle.fontSize);
如果您正在使用 textScaleFactor
缩放不是字体大小的尺寸,则没有将代码迁移到非线性缩放的通用规则,并且可能需要以不同的方式实现 UI。重用 MyTooltipBox
示例
MyTooltipBox(
size: chatBoxSize * textScaleFactor,
child: RichText(..., style: TextStyle(fontSize: 20)),
)
您可以选择使用“有效”文本缩放因子,通过在字体大小 20 上应用 TextScaler
:chatBoxSize * textScaler.scale(20) / 20
,或重新设计 UI 并让 Widget 假设其自己的内在大小。
在 Widget 子树中覆盖文本缩放策略
#要覆盖 Widget 子树中使用的现有 TextScaler
,请覆盖 MediaQuery
,如下所示
之前
MediaQuery(
data: MediaQuery.of(context).copyWith(textScaleFactor: 2.0),
child: child,
)
之后
MediaQuery(
data: MediaQuery.of(context).copyWith(textScaler: _myCustomTextScaler),
child: child,
)
但是,很少需要创建自定义 TextScaler
子类。MediaQuery.withNoTextScaling
(它创建一个 Widget,完全禁用其子树的文本缩放)和 MediaQuery.withClampedTextScaling
(它创建一个 Widget,将缩放后的字体大小限制在范围 [minScaleFactor * fontSize, maxScaleFactor * fontSize]
内)是涵盖需要覆盖文本缩放策略的常见情况的便捷方法。
示例
#禁用图标字体的文本缩放
之前
MediaQuery(
data: MediaQuery.of(context).copyWith(textScaleFactor: 1.0),
child: IconTheme(
data: ..,
child: icon,
),
)
之后
MediaQuery.withNoTextScaling(
child: IconTheme(
data: ...
child: icon,
),
)
防止内容过度缩放
之前
final mediaQueryData = MediaQuery.of(context);
MediaQuery(
data: mediaQueryData.copyWith(textScaleFactor: math.min(mediaQueryData.textScaleFactor, _kMaxTitleTextScaleFactor),
child: child,
)
之后
MediaQuery.withClampedTextScaling(
maxScaleFactor: _kMaxTitleTextScaleFactor,
child: title,
)
禁用非线性文本缩放
如果您想暂时选择退出 Android 14 上的非线性文本缩放,直到您的应用完全迁移,请在应用 Widget 树的顶部放置一个修改后的 MediaQuery
runApp(
Builder(builder: (context) {
final mediaQueryData = MediaQuery.of(context);
final mediaQueryDataWithLinearTextScaling = mediaQueryData
.copyWith(textScaler: TextScaler.linear(mediaQueryData.textScaler.textScaleFactor));
return MediaQuery(data: mediaQueryDataWithLinearTextScaling, child: realWidgetTree);
}),
);
此技巧使用已弃用的 textScaleFactor
API,并且一旦它从 Flutter API 中移除,它将停止工作。
时间线
#包含于版本:3.13.0-4.0.pre
稳定版发布:3.16
参考
#API 文档
TextScaler
MediaQuery.textScalerOf
MediaQuery.maybeTextScalerOf
MediaQuery.withNoTextScaling
MediaQuery.withClampedTextScaling
相关问题
相关 PR
除非另有说明,否则本网站上的文档反映了 Flutter 的最新稳定版本。页面上次更新于 2024-04-04。 查看源代码 或 报告问题.