咱們都知道在 Flutter 中能夠經過 fontFamily
來引入第三方字體,例如一般會將 svg 圖標轉換爲 iconfont.ttf
來實現矢量圖標的入,而通常狀況下咱們是不會設置 fontFamily
來使用第三方字體, 那默認狀況下 Flutter 使用的是什麼字體呢?android
會出現這個疑問,是由於有一天設計給我發了下面那張圖,問我 「爲何應用在蘋果平臺上的英文使用的是 PingFang SC
字體而不是 .SF UI Display
」 ? 正以下圖所示,它們的 G 字母在顯示效果上會有所差別,好比 平方的 G 有明顯的轉折線。git
這時候我不由產生的好奇,在 Flutter 中引擎默認到底是如何選擇字體?github
經過官方解釋,在 typography.dart
源碼中能夠看到,後端
Roboto
字體;.SF UI Display
或者 .SF UI Text
字體。The default font on Android is Roboto and on iOS it is .SF UI Display or .SF UI Text (SF meaning San Francisco). If you want to use a different font, then you will need to add it to your app.bash
那理論上在 iOS 使用的就是 .SF UI Display
字體纔對,由於以下源碼所示,在 Typography
中當 platform
是 iOS
時,使用的就是 Cupertino
相關的 TextTheme
,而 Typography
中的 white
和 black
屬性最終會應用到 ThemeData
的 defaultTextTheme
、 defaultPrimaryTextTheme
和 defaultAccentTextTheme
中,因此應該是使用 .SF
相關字體纔會,爲何會顯示的是 PingFang SC
的效果?網絡
factory Typography({
TargetPlatform platform = TargetPlatform.android,
TextTheme black,
TextTheme white,
TextTheme englishLike,
TextTheme dense,
TextTheme tall,
}) {
assert(platform != null || (black != null && white != null));
switch (platform) {
case TargetPlatform.iOS:
black ??= blackCupertino;
white ??= whiteCupertino;
break;
case TargetPlatform.android:
case TargetPlatform.fuchsia:
black ??= blackMountainView;
white ??= whiteMountainView;
}
englishLike ??= englishLike2014;
dense ??= dense2014;
tall ??= tall2014;
return Typography._(black, white, englishLike, dense, tall);
}
複製代碼
爲了搞清不一樣系統上字體的區別,在查閱了資料後可知:app
默認在 iOS 上:svg
中文字體:PingFang SC
post
英文字體:.SF UI Text
、.SF UI Display
測試
默認在 Android 上:
中文字體:Source Han Sans
/ Noto
英文字體:Roboto
也就是就 iOS 上除了 .SF
相關的字體外,還有 PingFang
字體的存在,這時候我忽然想起在以前的 《Flutter完整開發實戰詳解(十7、 實用技巧與填坑二)》 中,由於國際化多語言在 .SF
會出現顯示異常,因此使用了 fontFamilyFallback
強行指定了 PingFang SC
。
getCopyTextStyle(TextStyle textStyle) {
return textStyle.copyWith(fontFamilyFallback: ["PingFang SC", "Heiti SC"]);
}
複製代碼
終於破案了,由於當 fontFamily
沒有設置時,就會使用 fontFamilyFallback
中的第一個值將做爲首選字體,而在 fontFamilyFallback
中是順序匹配的,當fontFamily
和 fontFamilyFallback
二者都不提供,則將使用默認平臺字體。
而在 1.12.13 版本下測試發現 .SF
致使的問題已經修復了,因此只須要將 fontFamilyFallback
相關的代碼去除便可。
那在 iOS 上使用 .SF
字體有什麼好處? 按照網絡上的說法是:
SF Text
的字距及字母的半封閉空間,好比"a"!
上半部分會更大,因其可讀性更好,適用於更小的字體;SF Display
則適用於偏大的字體。具體分水嶺就是20pt
, 即字體小於20pt
時用Text
,大於等於20pt
時用Display
。更棒的是因爲
SF
屬於動態字體,Text
和Display
兩種字體族是系統動態匹配的,也就是說你不用費心去本身手動調節,系統自動根據字體的大小匹配這兩種顯示模式。
那能不能在 Android 上也使用.SF
字體呢?按照官方的說法:
San Francisco font(SF)
;San Francisco font(SF)
;可是由於 San Francisco font license
限制了該字體只能在 iOS、macOS 或 tvOS 上運行使用,因此若是使用了 Cupertino 主題的話,在 Android 上運行時使用 fallback font。
因此你以爲能不能在 Android 上使用?
最後再補充下,在官方的 architecture 中有提到,在 Flutter 中的文本呈現邏輯是有分層的,其中:
那讀完本篇,你奇奇怪怪的知識點有沒有增長?