-
前言
-
零、GSY历程
-
一、Dart语言和Flutter基础
-
二、 快速开发实战篇
-
三、 打包与填坑篇
-
四、 Redux、主题、国际化
-
五、 深入探索
-
六、 深入Widget原理
-
七、 深入布局原理
-
八、 实用技巧与填坑
-
九、 深入绘制原理
-
十、 深入图片加载流程
-
十一、全面深入理解Stream
-
十二、全面深入理解状态管理设计
-
十三、全面深入触摸和滑动原理
-
十四、混合开发打包 Android 篇
-
十五、全面理解State与Provider
-
十六、详解自定义布局实战
-
十七、实用技巧与填坑二
-
十八、 神奇的ScrollPhysics与Simulation
-
十九、 Android 和 iOS 打包提交审核指南
-
二十、 Android PlatformView 和键盘问题
-
二十一、 Flutter 画面渲染的全面解析
-
Flutter 跨平台框架应用实战-2019极光开发者大会
-
Flutter 面试知识点集锦
-
全网最全 Flutter 与 ReactNative深入对比分析
-
Flutter 开发实战与前景展望 - RTC Dev Meetup
-
Flutter Interact 的 Flutter 1.12 大进化和回顾
-
Flutter 升级 1.12 适配教程
-
Spuernova 是如何提升 Flutter 的生产力
-
Flutter 中的图文混排与原理解析
-
Flutter 实现视频全屏播放逻辑及解析
-
Flutter 上的一个 Bug 带你了解键盘与路由的另类知识点
-
Flutter 上默认的文本和字体知识点
-
带你深入理解 Flutter 中的字体“冷”知识
-
Flutter 1.17 中的导航解密和性能提升
-
Flutter 1.17 对列表图片的优化解析
-
Flutter 1.20 下的 Hybrid Composition 深度解析
-
2020 腾讯Techo Park - Flutter与大前端的革命
-
带你全面了解 Flutter,它好在哪里?它的坑在哪里? 应该怎么学?
-
Flutter 中键盘弹起时,Scaffold 发生了什么变化
-
Flutter 2.0 下混合开发浅析
-
Flutter 搭建 iOS 命令行服务打包发布全保姆式流程
-
不一样角度带你了解 Flutter 中的滑动列表实现
-
Flutter 跨平台框架应用实战-2019极光开发者大会
我们都知道在 Flutter 中可以通过 fontFamily
来引入第三方字体,例如通常会将 svg 图标转换为 iconfont.ttf
来实现矢量图标的入,而一般情况下我们是不会设置 fontFamily
来使用第三方字体, 那默认情况下 Flutter 使用的是什么字体呢?
会出现这个疑问,是因为有一天设计给我发了下面那张图,问我 “为什么应用在苹果平台上的英文使用的是 PingFang SC
字体而不是 .SF UI Display
” ? 正如下图所示,它们的 G 字母在显示效果上会有所差异,比如 平方的 G 有明显的转折线。
这时候我不禁产生的好奇,在 Flutter 中引擎默认究竟是如何选择字体?
通过官方解释,在
typography.dart
源码中可以看到,
- Flutter 默认在 Android 上使用的是
Roboto
字体; - 在 iOS 上使用的是
.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.
那理论上在 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);
}
copy
为了搞清不同系统上字体的区别,在查阅了资料后可知:
默认在 iOS 上:
中文字体:
PingFang SC
英文字体:
.SF UI Text
、.SF UI Display
默认在 Android 上:
中文字体:
Source Han Sans
/Noto
英文字体:
Roboto
也就是就 iOS 上除了 .SF
相关的字体外,还有 PingFang
字体的存在,这时候我突然想起在之前的 《Flutter完整开发实战详解(十七、 实用技巧与填坑二)》 中,因为国际化多语言在 .SF
会出现显示异常,所以使用了 fontFamilyFallback
强行指定了 PingFang SC
。
getCopyTextStyle(TextStyle textStyle) {
return textStyle.copyWith(fontFamilyFallback: ["PingFang SC", "Heiti SC"]);
}
copy
终于破案了,因为当 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
字体呢?按照官方的说法:
- 在使用 Material package 时,在 Android 上使用的是 ·Roboto font· ,而 iOS 使用的是
San Francisco font(SF)
; - 在使用 Cupertino package 时,默认主题始终使用
San Francisco font(SF)
;
但是因为 San Francisco font license
限制了该字体只能在 iOS、macOS 或 tvOS 上运行使用,所以如果使用了 Cupertino 主题的话,在 Android 上运行时使用 fallback font。
所以你觉得能不能在 Android 上使用?
最后再补充下,在官方的 architecture 中有提到,在 Flutter 中的文本呈现逻辑是有分层的,其中:
- 衍生自 Minikin 的 libtxt 库用于字体选择,分隔行等;
- HartBuzz 用于字形选择和成型;
- Skia作为 渲染 / GPU后端;
- 在 Android / Fuchsia 上使用 FreeType 渲染,在 iOS 上使用CoreGraphics 来渲染字体 。
那读完本篇,你奇奇怪怪的知识点有没有增加?