React Native 不使用Expo实现字体加载的方法咨询
无Expo的React Native项目实现异步加载字体方案
前置说明
你示例中使用expo-font实现的是应用启动阶段异步加载本地字体、加载完成后再渲染主内容的效果,纯React Native项目可以根据使用场景选择以下两种实现方案:
方案1:内置固定字体场景(最常用,适配你示例的需求)
如果字体是固定的,提前放到项目中打包到APP包内,不需要额外引入第三方库,操作步骤如下:
- 第一步:在项目根目录创建
assets/fonts文件夹,将所有字体文件放入该目录 - 第二步:在项目根目录新建
react-native.config.js文件,添加如下配置,用于告知React Native字体资源路径:
module.exports = { project: { ios: {}, android: {} }, assets: ['./assets/fonts/'] };
- 第三步:执行命令
npx react-native link,0.60及以上版本的React Native会自动将字体资源链接到iOS、Android原生项目中,无需手动修改原生配置。 - 第四步:编写应用加载逻辑,和你示例的逻辑对齐:
import React from 'react'; import { View, Text, StyleSheet } from 'react-native'; // 你可以用第三方启动屏库代替原来的AppLoading组件,也可以自定义加载页 import SplashScreen from 'react-native-splash-screen'; export default class App extends React.Component { state = { isFontLoaded: false } async componentDidMount() { // 内置字体已经在原生层完成加载,这里可直接做初始化,若需要模拟异步等待也可加延时逻辑 this.setState({ isFontLoaded: true }, () => { SplashScreen.hide(); // 字体加载完成后隐藏启动屏 }) } render() { if (!this.state.isFontLoaded) { // 无启动屏库的情况下可以直接返回自定义加载页 return <View style={styles.loadingPage} /> } return ( <View style={styles.container}> <Text style={{ fontFamily: 'Montserrat-ExtraBold', fontSize: 20 }}>粗体测试文本</Text> <Text style={{ fontFamily: 'Montserrat-Medium', fontSize: 20 }}>中粗测试文本</Text> <Text style={{ fontFamily: 'Montserrat-Regular', fontSize: 20 }}>常规测试文本</Text> </View> ) } } const styles = StyleSheet.create({ loadingPage: { flex: 1, backgroundColor: '#ffffff' }, container: { flex: 1, justifyContent: 'center', alignItems: 'center' } })
注意:fontFamily的取值必须和字体的PostScript名称完全一致,iOS会严格校验该名称,和字体文件名无关,你可以用字体查看工具打开字体文件确认对应的PostScript名称
方案2:运行时动态加载字体场景
如果需要在应用运行过程中动态加载字体(比如加载本地未内置的字体、从远程服务器下载字体),可以使用社区维护的react-native-dynamic-fonts库,安装配置完成后,实现逻辑和expo-font完全对齐,示例代码如下:
import React from 'react'; import { View, Text } from 'react-native'; import DynamicFonts from 'react-native-dynamic-fonts'; export default class App extends React.Component { state = { isFontLoaded: false } async componentDidMount() { await Promise.all([ DynamicFonts.load('Montserrat-ExtraBold', require('./assets/fonts/Montserrat-ExtraBold.otf')), DynamicFonts.load('Montserrat-Medium', require('./assets/fonts/Montserrat-Medium.otf')), DynamicFonts.load('Montserrat-Regular', require('./assets/fonts/Montserrat-Regular.otf')) ]) this.setState({ isFontLoaded: true }) } render() { if (!this.state.isFontLoaded) { return <View style={{ flex: 1, backgroundColor: '#fff' }} /> } return ( <View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}> <Text style={{ fontFamily: 'Montserrat-ExtraBold', fontSize: 22 }}>动态加载字体测试</Text> </View> ) } }
内容的提问来源于stack exchange,提问作者vamsi krishna
相关产品推荐
相关产品推荐

