字体
编辑
了解如何在应用中使用本地文件或 Google Font 包来集成自定义字体
Android 和 iOS 自带一套平台字体。为了提供一致的用户体验并提升应用的品牌形象,可以使用自定义字体。
本指南介绍了在项目中添加和加载自定义字体的不同方法,并提供与字体相关的额外信息。
添加自定义字体
有两种方法可以将自定义字体添加到您的项目中:
- 将字体文件放入本地资产中。例如,将字体文件放在 assets/fonts 目录。
- 安装一个 Google Font 包。例如,安装
@expo-google-fonts/inter包。
支持的字体格式
Expo SDK 官方在 Android、iOS 和网页平台上原生支持 OTF 和 TTF 字体格式。如果你的字体是其他字体格式,则需要在项目中进行高级配置以支持该格式。
可变字体
可变字体(包括 OTF 和 TTF 的可变字体实现)并非在所有平台上都得到支持。要获得完整的跨平台支持,请使用静态字体。或者,使用诸如 fontTools 之类的工具,从可变字体中提取你想要使用的特定轴配置,并将其保存为单独的字体文件。
如何在 OTF 与 TTF 之间进行选择
如果你使用的字体同时有 OTF 和 TTF 版本,优先选择 OTF。.otf 文件比 .ttf 文件小。某些情况下,OTF 在某些上下文中还会有略微更好的渲染效果。
使用本地图形字体
将文件复制到你项目的 assets/fonts 目录中。
assets/fonts 目录路径是在 React Native 应用中放置字体文件的常见约定。若遵循自定义约定,您也可以将这些文件放在其他位置。
在项目中使用本地字体文件的两种方式:
- 将字体文件嵌入使用
expo-font配置插件 。 - 在运行时使用
useFonts钩子异步加载字体文件。
使用 expo-font 配置插件
expo-font 配置插件允许在项目的原生代码中嵌入一个或多个字体文件。它对 Android 和 iOS 同时支持 ttf 和 otf,并且仅在 iOS 上支持 woff 和 woff2。这是向应用中添加字体的推荐方法,原因如下:
- 字体在设备上应用启动时即可立即可用。
- 应用启动时无需额外的代码来异步加载字体。
- 字体在应用安装的所有设备上都可用,因为它们被捆绑在应用中。
然而,这种方法也有一些局限性:
- 不适用于 Expo Go,因为此方法需要 创建开发构建 。
要在项目中嵌入字体,请按照以下步骤:
1
在项目中添加自定义字体文件后,安装 expo-font 库。
- npx expo install expo-font2
将配置插件添加到你的 应用配置 文件中。配置必须包含使用 fonts, android 或 ios 属性的字体文件路径,这些属性接收一个或多个字体定义的数组。每个字体文件的路径相对于项目根目录。
下面的示例展示了所有有效的字体指定方式:可以是一个包含 fontFamily 和其他属性的对象数组,,也可以是字体文件路径的数组。
对于 Android,您可以指定 fontFamily、weight,以及可选的 style(默认为 "normal"),这将把字体嵌入为本地 XML 资源 。如果您仅在数组中提供字体文件路径,文件名将成为 Android 上的字体族名称。iOS 始终从字体文件本身提取字体族名称。
如果你计划仅使用 fontFamily 来引用字体,请提供一个字体路径数组(请参见下方的 FiraSans-MediumItalic.ttf)并遵循我们在 文件命名的推荐 。
如果你想使用 fontFamily、weight 和 style 的组合来引用字体,请提供一个对象数组(见下方的 Inter)。
{ "expo": { "plugins": [ [ "expo-font", { "fonts": [ "./assets/fonts/FiraSans-MediumItalic.ttf" ], "android": { "fonts": [ { "fontFamily": "Inter", "fontDefinitions": [ { "path": "./assets/fonts/Inter-BoldItalic.ttf", "weight": 700, "style": "italic" }, { "path": "./assets/fonts/Inter-Bold.ttf", "weight": 700 } ] } ] }, "ios": { "fonts": ["./assets/fonts/Inter-Bold.ttf", "./assets/fonts/Inter-BoldItalic.ttf"] } } ] ] } }
3
在使用配置插件嵌入字体后,创建一个 新的开发构建 ,并在你的设备、Android 模拟器或 iOS 模拟器上安装。
你可以通过指定 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>
在现有的 React Native 项目中使用此方法?
- Android: 将字体文件复制到 android/app/src/main/assets/fonts.
- iOS: 请在 Apple Developer 文档中查看 Adding a Custom Font to Your App。
如何确定要使用的字体族名称
-
如果你按照上面所述将字体作为文件路径数组提供,在 Android 上,文件名(不包含扩展名)将成为字体族名称。在 iOS 上,字体族名称是从字体文件本身读取的。我们建议将字体文件命名为与其 PostScript name 相同,这样在两个平台上的字体族名称就保持一致。
-
如果你使用对象语法,请提供 "Family Name"。可以在 macOS 的 Font Book 应用、fontdrop.info 或其他程序中找到。
字体文件的 PostScript 名称是什么?
字体文件的 PostScript 名称 是按 Adobe 的 PostScript 标准分配给字体的唯一标识符。它被操作系统和应用程序用于引用该字体。它不是字体的 显示名称 。
例如,Inter Black 字体文件的 PostScript 名称是 Inter-Black。
来自 macOS 的 Font Book 应用截图。
使用 useFonts 钩子
useFonts 钩子来自 expo-font 库,允许异步加载字体文件。该钩子会跟踪加载状态,并在应用初始化时加载字体。
它可与所有 Expo SDK 版本以及 Expo Go 一起使用。要在使用 useFonts 钩子的项目中加载字体,请按照以下步骤:
在项目中添加自定义字体文件后,安装 expo-font 和 expo-splash-screen 库。
1
- npx expo install expo-font expo-splash-screenexpo-splash-screen 库提供 SplashScreen 组件,您可以使用它在字体加载并就绪之前防止应用渲染。
2
在项目中的顶层组件(例如根布局 app/layout.tsx 文件)中使用 useFonts 钩子映射字体文件:
import { useFonts } from 'expo-font'; import * as SplashScreen from 'expo-splash-screen'; import {useEffect} from 'react'; SplashScreen.preventAutoHideAsync(); export default function RootLayout() { const [loaded, error] = useFonts({ 'Inter-Black': require('./assets/fonts/Inter-Black.otf'), }); useEffect(() => { if (loaded || error) { SplashScreen.hideAsync(); } }, [loaded, error]); if (!loaded && !error) { return null; } return ( %%placeholder-start%%... %%placeholder-end%% ) }
3
在 React 组件中通过使用 fontFamily 样式属性来使用 <Text> 的字体:
<Text style={{ fontFamily: 'Inter-Black' }}>Inter Black</Text>
使用 Google Fonts
Expo 对 Google Fonts 列出的所有字体提供一流的支持。它们可以通过 Google Fonts 使用 @expo-google-fonts 库获得。使用此库中的任意字体包,您可以快速集成该字体及其变体。
在你的项目中使用 Google Font 的两种方式:
- 使用
expo-font配置插件 将已安装的字体嵌入。 - 在运行时异步地通过
useFonts钩子加载已安装的字体。
使用 expo-font 配置插件
注意: 使用
expo-font配置插件嵌入 Google Fonts,与自行嵌入自定义字体具有相同的好处与限制。有关更多信息,请参见 使用本地字体文件配合expo-font配置插件 。
1
安装字体包。例如,要使用 Inter Black 字体,请使用下面的命令安装 @expo-google-fonts/inter 包。
- npx expo install expo-font @expo-google-fonts/inter2
3
在使用配置插件嵌入字体后,创建一个 新的开发构建 并将其安装在你的设备、Android 模拟器或 iOS 模拟器上。
在 Android 上,你可以使用字体文件名。例如,Inter_900Black。在 iOS 上,使用字体及其重量名称(PostScript 名称 )。下方示例展示如何使用 Platform 为每个平台选择正确的字体族名称:
import { Platform } from 'react-native'; // Inside a React component: <Text style={{ fontFamily: Platform.select({ android: 'Inter_900Black', ios: 'Inter-Black', }), }}> Inter Black </Text>
使用 useFonts hook
注意: 使用
useFontshook 加载 Google Font 与自行嵌入自定义字体具有相同的优点与限制。有关更多信息,请参阅 使用本地字体文件与useFontshook。
每个 google Fonts 包都提供 useFonts hook,用以异步加载字体。该 hook 会跟踪加载状态,并在应用初始化时加载字体。该字体包还会导入字体文件,因此你无需显式导入。
1
安装 Google Fonts 包、expo-font 和 expo-splash-screen 库。
- npx expo install @expo-google-fonts/inter expo-font expo-splash-screenexpo-splash-screen 库提供了 SplashScreen 组件,您可以使用它在字体加载并就绪之前阻止渲染应用。
2
安装字体包后,在项目中的顶层组件(例如根布局文件 app/layout.tsx)中使用 useFonts 钩子映射字体:
// Rest of the import statements import { Inter_900Black, useFonts } from '@expo-google-fonts/inter'; import * as SplashScreen from 'expo-splash-screen'; import {useEffect} from 'react'; SplashScreen.preventAutoHideAsync(); export default function RootLayout() { const [loaded, error] = useFonts({ Inter_900Black, }); useEffect(() => { if (loaded || error) { SplashScreen.hideAsync(); } }, [loaded, error]); if (!loaded && !error) { return null; } return ( %%placeholder-start%%... %%placeholder-end%% ) }
3
在 React 组件中使用 <Text> 的字体,通过 fontFamily 样式属性:
<Text style={{ fontFamily: 'Inter_900Black' }}>Inter Black</Text>
附加信息
最小示例
expo-font 的用法请在 Expo Fonts API 参考中的使用部分查看使用自定义字体的最小示例。
超出 OTF 和 TTF
如果你的字体格式不是 OTF 或 TTF,你需要 自定义 Metro bundler 配置,将其作为额外的资源 ,以使其能够工作。在某些情况下,渲染一个平台不支持的字体格式可能会导致应用崩溃。
供参考,以下表格提供在每个原生平台上可使用的列表格式:
| 格式 | Android | iOS | Web |
|---|---|---|---|
| bdf | |||
| dfont | |||
| eot | |||
| fon | |||
| otf | |||
| ps | |||
| svg | |||
| ttc | |||
| ttf | |||
| woff | |||
| woff2 |
平台内置字体
如果你不想通过指定 fontFamily 使用自定义字体,系统默认字体将被使用。每个平台都具有一组内置字体。在 Android 上,默认字体是 Roboto。在 iOS 上,是 SF Pro。
平台的默认字体通常易于阅读。然而,当系统默认字体被更改为另一种不易阅读的字体时,也不要感到惊讶。在这种情况下,使用你的自定义字体,这样你就可以对用户看到的内容进行精确控制。
处理 @expo/vector-icons 的初始加载
当 @expo/vector-icons 库的图标首次加载时,它们在你的应用中会以不可见的图标呈现。加载完成后,它们会被缓存,供应用的后续使用。为避免在应用首次加载时显示不可见的图标,可以在初始加载屏幕阶段通过 useFonts 进行预加载。例如:
import { useFonts } from 'expo-font'; import Ionicons from '@expo/vector-icons/Ionicons'; export default function RootLayout() { useFonts([require('./assets/fonts/Inter-Black.otf', Ionicons.font)]); return ( %%placeholder-start%%... %%placeholder-end%% ) }
现在,您可以在 React 组件中使用 Ionicons 库中的任意图标:
<Ionicons name="checkmark-circle" size={32} color="green" />
了解在你的 Expo 应用中使用各种类型图标的方法,包括矢量图标、自定义图标字体、图标图片和图标按钮。
直接从网络加载远程字体
如果你正在加载远程字体,请确保它们来自一个正确配置 CORS 的源 。如果你不这样做,远程字体在网页平台上可能无法正确加载。
从本地资源加载字体是应用程序中加载字体的最安全方式。当将字体作为本地资源包含时,在你将应用提交到应用商店后,这些字体会随应用下载打包并可立即使用。你无需担心 CORS 或其他潜在问题。
然而,直接从网页加载字体文件,是通过将 require('./assets/fonts/FontName.otf') 替换为下面示例所示的字体 URL 来实现。
import { useFonts } from 'expo-font'; import { Text, View, StyleSheet } from 'react-native'; export default function App() { const [loaded, error] = useFonts({ 'Inter-SemiBoldItalic': 'https://rsms.me/inter/font-files/Inter-SemiBoldItalic.otf?v=3.12', }); if (!loaded || !error) { return null; } return ( <View style={styles.container}> <Text style={{ fontFamily: 'Inter-SemiBoldItalic', fontSize: 30 }}>Inter SemiBoldItalic</Text> <Text style={{ fontSize: 30 }}>Platform Default</Text> </View> ); } const styles = StyleSheet.create({ container: { flex: 1, justifyContent: 'center', alignItems: 'center', }, });