棄用 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 中移除。
新的類別在下列 API 中取代了 double textScaleFactor
(double textScaleFactor
-> TextScaler textScaler
)
繪圖程式庫
#受影響的 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' 已棄用,不應使用。 |
小工具程式庫
#受影響的 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 框架提供的 Widget 已經遷移。只有在您使用前面表格中列出的任何已棄用符號時才需要遷移。
遷移公開 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)),
)
您可以選擇將 TextScaler
應用於字體大小 20 來使用「有效」的文字縮放比例: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 上暫時退出非線性文字縮放,直到您的應用程式完全遷移為止,請將修改後的 MediaQuery
放在您的應用程式 Widget 樹的頂部
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。 檢視來源 或 回報問題。