This documentation is available as Markdown for AI agents and LLMs. See the full Markdown index or append .md to any documentation URL.
字体
编辑页面
了解如何使用本地文件或 Google 字体包将自定义字体集成到你的应用中
Android 和 iOS 自带各自的平台字体。为了提供一致的用户体验并增强应用的品牌形象,你可以使用自定义字体。
本指南介绍了将自定义字体添加并加载到项目中的不同方式,也提供了与字体相关的其他信息。
添加自定义字体
你可以通过两种方式将自定义字体添加到项目中:
- 将字体文件添加到本地资源中。例如,放在 assets/fonts 目录下的字体文件。
- 安装 Google 字体包。例如,安装
@expo-google-fonts/inter包。
支持的字体格式
Expo SDK 官方支持在 Android、iOS 和 web 平台上使用 OTF 和 TTF 字体格式。如果你的字体是其他格式,则需要进行高级配置才能在项目中支持该格式。
可变字体
可变字体在一个文件中包含多种字形。你无需为每种字重都打包一个文件,而是只需打包一个文件,然后使用 fontWeight 和 fontStyle 样式属性选择字形。配置插件和 useFonts hook 均支持可变字体。
信息 Android 和 iOS 在 SDK 58 及更高版本中支持可变字体。在较早版本中,请使用静态字体文件。
每个平台确定文件提供哪些字形的方式各不相同,因此请先检查文件,再决定是否使用:
- Android 会读取
wght轴,并从中绘制fontWeight可以指定的每种字重,但不能超出该轴声明的范围。这需要 Android 10 或更高版本。在较早版本中,字体会以默认字重呈现,Android 则通过加粗字母来生成粗体。 - iOS 会读取文件声明的_命名实例_。命名实例是字体设计师赋予名称并为每个轴设定固定位置的字形,例如 “Bold” 或 “Condensed Light”。React Native 会选择字重最接近你所请求字重的命名实例。如果没有命名实例涵盖某个字重,则无法使用该字重。如果文件未声明命名实例,则只会呈现默认字形。
对于 fontStyle: 'italic',Android 会在 Android 15 及更高版本中应用字体的 ital 轴。在较早版本中,Android 会通过倾斜正体字母来生成斜体。iOS 则使用文件中的斜体命名实例。
在 React Native 0.88(Expo SDK 58)及更高版本中,你还可以使用 fontVariationSettings 样式属性,直接在组件上设置任意轴,例如 fontVariationSettings: "'wght' 650, 'wdth' 90"。该属性适用于两个平台上的 <Text> 和 <TextInput>(Android 8 及更高版本),并且你在此处设置的轴优先级高于 fontWeight 和 fontStyle。
可以使用 fontTools 等工具检查文件的轴和命名实例。如果你在某个平台上无法使用所需字形,可以使用 fontTools 提取该轴配置,并将其保存为单独的静态字体文件。
如何在 OTF 和 TTF 之间选择
如果你使用的字体同时有 OTF 和 TTF 版本,优先选择 OTF。.otf 文件比 .ttf 文件更小。有时,在某些场景下 OTF 的渲染效果也会稍好一些。
使用本地字体文件
将文件复制到项目的 assets/fonts 目录中。
信息 assets/fonts 目录路径是在 React Native 应用中放置字体文件的一种常见约定。如果你遵循自定义约定,也可以把这些文件放在其他位置。
在项目中使用本地字体文件有两种方式:
- 使用
expo-font配置插件嵌入字体文件(仅限 Android 和 iOS)。 - 在运行时使用
useFontshook 加载字体文件(支持 Android、iOS 和 web)。
使用 expo-font 配置插件
expo-font 配置插件允许将一个或多个字体文件嵌入到项目的原生代码中。它支持 Android 和 iOS 的 ttf 和 otf,而 woff 和 woff2 仅在 iOS 上受支持。
注意: 配置插件仅在原生平台(Android 和 iOS)上运行。对于 web,请改用
useFontshook。
由于以下优点,这是向应用添加字体的推荐方式:
- 应用在设备上启动时,字体即可立即可用。
- 应用启动时无需额外代码来异步加载字体。
- 由于字体被打包进应用,因此在所有安装了该应用的设备上都能一致地使用字体。
不过,这种方式也有一些限制:
- 由于此方法要求创建开发构建,因此无法与 Expo Go 一起使用。
要将字体嵌入项目,请按以下步骤操作:
1
在项目中添加自定义字体文件后,安装 expo-font 库。
2
将配置插件添加到你的 app config 文件中。配置必须使用 fonts、android 或 ios 属性包含字体文件路径,这些属性接受一个或多个字体定义的数组。每个字体文件的路径相对于项目根目录。
下面的示例展示了字体可指定的所有有效方式:可以是一个包含 fontFamily 和其他属性的对象数组,也可以是一个字体文件路径数组。
对于 Android,你可以指定 fontFamily、weight,以及可选的 style(默认为 "normal"),这样字体会被嵌入为原生 XML 资源。如果你在数组中只提供字体文件路径,那么文件名会成为 Android 上的字体族名称。iOS 总是从字体文件本身提取字体族名称。
如果你计划只使用 fontFamily 来引用字体,请提供字体路径数组(如下方的 FiraSans-MediumItalic.ttf 所示),并遵循我们关于如何确定要使用哪个字体族名称的建议。
如果你想通过 fontFamily、weight 和 style 的组合来引用字体,请提供对象数组(如下方的 Inter 所示)。
对于 Android 上的可变字体,请在每个 fontDefinitions 条目中声明文件路径,或者在 fontFamily 旁边声明一次,以避免重复。每个定义都需要一组 weight 和 style 值,且同一字体族中的其他定义不能使用相同的组合,因为 Android 会根据这组值解析字体族。
style 会选择与 fontStyle 匹配的字形,但不会倾斜字形。若要从正体文件生成斜体,请在 axes 中设置倾斜轴,例如 slnt 或 ital。
axes 接受字体声明的任何变化轴,例如用于选择窄体字形的 wdth。轴标签为四个字符,且区分大小写。已注册的轴(ital、opsz、slnt、wdth、wght)均为小写,而字体自带的轴为大写,例如 GRAD。除非你在 axes 中覆盖 weight,否则 weight 会设置 wght。
在 iOS 上,path 和 axes 不起作用。请像静态字体一样,将可变字体文件列在 ios.fonts 中。你可以选择的字形是文件声明的命名实例。要使用轴上的其他位置,请在 React Native 0.88 及更高版本中使用 fontVariationSettings 样式属性。
3
使用配置插件嵌入字体后,创建一个新的开发构建,并将其安装到你的设备、Android Emulator 或 iOS Simulator 上。
你可以通过指定 fontFamily 样式属性在 <Text> 中使用该字体。下面的示例与上面配置中定义的字体相对应。
<Text style={{ fontFamily: 'Inter', fontWeight: '700' }}>Inter Bold</Text> <Text style={{ fontFamily: 'Inter', fontWeight: '700', fontStyle: 'italic' }}>Inter Bold Italic</Text> <Text style={{ fontFamily: 'FiraSans-MediumItalic' }}>Fira Sans Medium Italic</Text> <Text style={{ fontFamily: 'Roboto Flex', fontWeight: '400', fontStyle: 'italic' }}>Roboto Flex Italic</Text>
在现有 React Native 项目中使用这种方式?
- Android: 将字体文件复制到 android/app/src/main/assets/fonts。
- iOS: 参见 Apple Developer 文档中的 Adding a Custom Font to Your App。
如何确定要使用哪个字体族名称
-
如果你将字体以文件路径数组的形式提供(如上所述),在 Android 上,文件名(不含扩展名)会成为字体族名称。在 iOS 上,字体族名称会从字体文件本身读取。我们建议将字体文件命名为与其 PostScript 名称相同,以便两个平台上的字体族名称保持一致。
-
如果你使用对象语法,请提供“Family Name”。你可以在 macOS 的 Font Book 应用、fontdrop.info 或其他程序中找到它。
字体文件的 PostScript 名称是什么?
字体文件的 PostScript 名称 是按照 Adobe 的 PostScript 标准分配给字体的唯一标识符。操作系统和应用使用它来引用该字体。它不是字体的 显示名称。
例如,Inter Black 字体文件的 PostScript 名称是 Inter-Black。
macOS 上的 Font Book 应用截图。
使用 useFonts hook
expo-font 库中的 useFonts hook 允许异步加载字体文件。这个 hook 会跟踪加载状态,并在应用初始化时加载字体。
它适用于所有 Expo SDK 版本以及 Expo Go。要在项目中使用 useFonts hook 加载字体,请按以下步骤操作:
1
在项目中添加自定义字体文件后,安装 expo-font 和 expo-splash-screen 库。
expo-splash-screen 库提供了 SplashScreen 组件,你可以用它在字体加载完成之前阻止应用渲染。
2
在项目中的顶层组件中,例如根布局(src/app/_layout.tsx)文件,使用 useFonts hook 映射字体文件:
3
在 React 组件中通过 fontFamily 样式属性在 <Text> 上使用该字体:
<Text style={{ fontFamily: 'Inter-Black' }}>Inter Black</Text>
如果映射的文件是可变字体,请使用 fontWeight 和 fontStyle 样式属性选择字形:
<Text style={{ fontFamily: 'Roboto Flex', fontWeight: '300' }}>Roboto Flex Light</Text> <Text style={{ fontFamily: 'Roboto Flex', fontWeight: '700' }}>Roboto Flex Bold</Text>
useFonts 只读取字重轴。要设置其他轴,例如 wdth 或 slnt,请在 Android 上使用配置插件嵌入字体,或者在 React Native 0.88 及更高版本中设置 fontVariationSettings 样式属性。
为同一字体族加载多个字重和样式
信息 在 SDK 58 及更高版本中,可以在同一字体族名称下加载多个字体文件。
上面的映射语法会将每个键视为一个单独的字体族。要在同一个 fontFamily 名称下加载多个字体文件(例如常规、粗体和斜体字形),请向 useFonts 传递 FontFamilyDefinition 数组,而不是映射:
然后使用 fontWeight 和 fontStyle 样式属性选择字形:
<Text style={{ fontFamily: 'Inter', fontWeight: '700' }}>Inter Bold</Text> <Text style={{ fontFamily: 'Inter', fontWeight: '400', fontStyle: 'italic' }}>Inter Italic</Text>
请在一次调用中声明某个字体族的所有字形。一个 fontFamily 只会加载一次,因此后续针对已加载名称的 loadAsync 或 useFonts 调用不会向其中添加字形。这也适用于两种调用方式之间的情形:执行 useFonts({ Inter: require('./assets/fonts/Inter-Regular.otf') }) 后,再为 Inter 传递数组也不会加载更多字体。
为多字形字体族中的每个字形声明 weight 和 style。Web 需要这两个值,显式声明也能确保三个平台保持一致。唯一的例外是单个可变字体文件:请将其 style 留空,并将 weight 留空或声明一个字重范围,例如 '100 900'。这样 Android 会为每个 fontWeight 实例化字体的 wght 轴,而不是将其固定为单一字重。
平台说明:
- Android 使用声明的
weight和style值;未声明时则回退到字体文件中的值。声明weight会将可变字体字形固定为该字重,其他字重由 Android 合成。在 API 29 以下(Android 10 以下),只会加载默认字形,并根据声明的值选择(最接近字重 400 的正体字形)。通过配置插件嵌入的字体使用 Android 的 XML 字体资源,不受此限制。 - iOS 根据字体文件中嵌入的字重和样式元数据匹配字形。只有当文件中没有可读取的元数据时,它才会使用声明的
weight和style值来选择字体族的默认字形。 - Web 会为每个字形生成一条 CSS
@font-face规则,并使用声明的weight和style值。CSS 无法读取字体文件中的元数据,因此未声明style的字形会以正体呈现。同一字体族中的两个字形如果都未声明相同的值,就会生成相同的 CSS 规则,浏览器会呈现最后一个字形。
使用 Google Fonts
Expo 对 Google Fonts 中列出的所有字体提供一流支持。它们可通过 @expo-google-fonts 库使用。使用该库中的任意字体包,你都可以快速集成该字体及其变体。
在项目中使用 Google 字体有两种方式:
- 使用
expo-font配置插件嵌入已安装的字体。 - 在运行时通过
useFontshook 异步加载已安装的字体。
使用 expo-font 配置插件
注意: 使用
expo-font配置插件嵌入 Google 字体,与自行嵌入自定义字体具有相同的优点和限制。更多信息请参见使用expo-font配置插件加载本地字体文件。
1
安装字体包。例如,要使用 Inter Black 字体,请使用下面的命令安装 @expo-google-fonts/inter 包。
2
将配置插件添加到你的 app config 文件中。配置必须包含字体文件的路径,并使用 fonts 属性,该属性接受一个或多个字体文件组成的数组。字体文件路径是从 node_modules 目录中的字体包定义的。例如,如果你有一个名为 @expo-google-fonts/inter 的字体包,那么文件名就是 Inter_900Black.ttf。
3
使用配置插件嵌入字体后,创建一个新的开发构建版本,并将其安装到你的设备、Android 模拟器或 iOS 模拟器上。
在 Android 上,你可以使用字体文件名。例如,Inter_900Black。在 iOS 上,使用字体及其字重名称(PostScript 名称)。下面的示例演示了如何使用 Platform 为每个平台选择正确的字体族名称:
import { Platform } from 'react-native'; // 在 React 组件内部: <Text style={{ fontFamily: Platform.select({ android: 'Inter_900Black', ios: 'Inter-Black', }), }}> Inter Black </Text>
使用 useFonts hook
注意: 使用
useFontshook 加载 Google 字体,与自行嵌入自定义字体具有相同的优点和限制。更多信息请参见使用useFontshook 加载本地字体文件。
每个 Google Fonts 包都提供了 useFonts hook 来异步加载字体。该 hook 会跟踪加载状态,并在应用初始化时加载字体。字体包还会导入字体文件,因此你无需显式导入它。
1
安装 Google Fonts 包、expo-font 和 expo-splash-screen 库。
expo-splash-screen 库提供了 SplashScreen 组件,你可以用它在字体加载完成之前阻止应用渲染。
2
安装字体包后,在项目中的顶层组件中使用 useFonts hook 映射字体,例如根布局(src/app/_layout.tsx)文件:
3
在 React 组件中,通过在 <Text> 上使用 fontFamily 样式属性来使用该字体:
<Text style={{ fontFamily: 'Inter_900Black' }}>Inter Black</Text>
附加信息
最小示例
expo-font 用法请参阅 Expo Fonts API 参考中的用法部分,了解使用自定义字体的最小示例。
OTF 和 TTF 之外的格式
如果你的字体格式不是 OTF 或 TTF,你必须自定义 Metro bundler 配置,将其作为额外资源包含进去,它才会生效。在某些情况下,渲染平台不支持的字体格式可能会导致你的应用崩溃。
作为参考,下表提供了在各个原生平台上可用的格式列表:
平台内置字体
如果你不想通过指定 fontFamily 来使用自定义字体,那么将使用平台的默认字体。每个平台都有一组内置字体。在 Android 上,默认字体是 Roboto。在 iOS 上,是 SF Pro。
平台的默认字体通常都很易读。不过,如果系统默认字体被更改为另一种不易读的字体,也不必惊讶。在这种情况下,请使用你的自定义字体,这样你就可以精确控制用户将看到的内容。
处理 @expo/vector-icons 的首次加载
当 @expo/vector-icons 库中的图标首次加载时,它们在你的应用中会显示为不可见图标。加载完成后,它们会被缓存,以供应用后续使用。为了避免在应用首次加载时显示不可见图标,请在初始加载屏幕期间使用 useFonts 进行预加载。例如:
现在,你可以在 React 组件中使用 Ionicons 库中的任意图标:
<Ionicons name="checkmark-circle" size={32} color="green" />
了解如何在你的 Expo 应用中使用各种类型的图标,包括矢量图标、自定义图标字体、图标图片和图标按钮。
直接从网页加载远程字体
如果你正在加载远程字体,请确保它们是从已正确配置 CORS 的源提供的。如果你不这样做,你的远程字体在 web 平台上可能无法正常加载。
从本地资源加载字体是在应用中加载字体最安全的方式。将字体作为本地资源包含后,当你将应用提交到应用商店时,这些字体会与应用下载包一起打包,并可立即使用。你无需担心 CORS 或其他潜在问题。
不过,直接从网页加载字体文件的方法是将 require('./assets/fonts/FontName.otf') 替换为字体的 URL,如下面的示例所示。