React Native Expo 无法加载字体

5

我是一名 React Native 初学者!

我正在尝试在使用 Expo 的 React Native 应用程序中使用自定义字体。我尝试按照 https://docs.expo.io/versions/latest/guides/using-custom-fonts.html#using-custom-fonts 中的指示进行操作,但没有成功。

这是我的 App.js:

import React from 'react';
import { View, Text, TouchableOpacity, TextInput, StyleSheet, AsyncStorage, Alert, Platform, NativeModules } from 'react-native';
import { Expo } from 'expo';

import { StackNavigator } from 'react-navigation';
import LoginScreen from './src/views/LoginScreen';
import AuthenticatedScreen from './src/views/AuthenticatedScreen';

import './ReactotronConfig'

import styles from './src/styles/ParentStyles'

const { StatusBarManager } = NativeModules;

const RootStack = StackNavigator(
    {
        Login: { screen: LoginScreen },
        Authenticated: { screen: AuthenticatedScreen }
    },
    { initialRouteName: 'Login'}
);

const STATUSBAR_HEIGHT = Platform.OS === 'ios' ? 20 : StatusBarManager.HEIGHT;

export default class App extends React.Component {
    state = {
        fontLoaded: false,
    };

    async componentDidMount() {
        await Expo.Font.loadAsync({
            'open-sans-bold': require('./src/assets/fonts/OpenSans-Bold.ttf'),
        });
        console.log('running')
        this.setState({ fontLoaded: true });
    }

  render() {
    console.log('statusBarHeight: ' + StatusBarManager.HEIGHT);
    return (<RootStack />);
  }
}

console.disableYellowBox = true;

我正在尝试在登录页面中调用open-sans-bold字体,代码如下:
render() {
    return (
        <View style = { parentStyles.container } >
            <View style={ loginStyles.backgroundImageContainer }>
                <Image style={ loginStyles.backgroundImage } source={require('../assets/img/splash.png')} />
            </View>
            <View style={ loginStyles.logoImageContainer } >
                <Image style={ loginStyles.logoImage } source={require('../assets/img/PMlogo.png')} resizeMode="contain"/>
            </View>
            <View style={{flex: 50 }} >
                //***CALLING FONT HERE*** 
                <Text style={{ fontFamily: 'open-sans-bold', fontSize: 56 }}>Email</Text>
                <TextInput style = {loginStyles.input}
                    underlineColorAndroid = "transparent"
                    placeholder = "Email"
                    placeholderTextColor = "red"
                    autoCapitalize = "none"
                    ref = { input => { this.textInputEmail = input }}
                    onChangeText = { this.handleEmail }/>

                <TextInput style = { loginStyles.input }
                    underlineColorAndroid = "transparent"
                    placeholder = "Password"
                    placeholderTextColor = "red"
                    autoCapitalize = "none"
                    ref = { input => { this.textInputPassword = input }}
                    onChangeText = { this.handlePassword }/>

                <TouchableOpacity
                    style = {loginStyles.submitButton}
                    onPress = { () => this.login(this.state.email, this.state.password) }
                    >
                    <Text style = { loginStyles.submitButtonText }> Login </Text>
                </TouchableOpacity>
            </View>
        </View>
    )

}

很不幸,当我运行这个程序时,我遇到了以下错误:

fontFamily 'open-sans-bold' is not a system font and has not been loaded through Expo.Font.loadAsync.

- If you intended to use a system font, make sure you typed the name correctly and that it is supported by your device operating system.

- If this is a custom font, be sure to load it with Expo.Font.loadAsync.

任何帮助都非常感激!!

4个回答

3
嘿,兄弟,这是一个适用于 app.js 的正确工作代码,只需根据你的情况进行调整。
import React from "react";
import { AppLoading, Font } from "expo";
import { StyleSheet, Text, View } from "react-native";

 export default class App extends React.Component {
     state = {
       loaded: false,
     };

     componentWillMount() {
       this._loadAssetsAsync();
     }

     _loadAssetsAsync = async () => {
       await Font.loadAsync({
         diplomata: require("./assets/fonts/DiplomataSC-Regular.ttf"),
       });
       this.setState({ loaded: true });
     };

     render() {
       if (!this.state.loaded) {
         return <AppLoading />;
       }

     return (
      <View style={styles.container}>
        <Text style={styles.info}>
          Look, you can load this font! Now the question is, should you use it?
          Probably not. But you can load any font.
        </Text>
      </View>
      );
     }
    }

  const styles = StyleSheet.create({
       container: {
         flex: 1,
         backgroundColor: "#fff",
         alignItems: "center",
         justifyContent: "center",
         padding: 30,
       },
       info: {
         fontFamily: "diplomata",
         textAlign: "center",
         fontSize: 14,
       },
   });

AppLoading现已弃用。 - realtebo

0
由于某些奇怪的原因,函数式组件方法对我不起作用,我需要改为类组件。
以下是基于React Native Cookbook的最小工作示例:
import React from 'react';
import { AppLoading } from 'expo';
import * as Font from 'expo-font';
import YourComponent from 'path/to/component';


export default class App extends React.Component {
  state = {
    fontLoaded: false
  };

  async componentDidMount() {
    await Font.loadAsync({
      'open-sans': require('./assets/fonts/OpenSans-Regular.ttf'),
      'open-sans-bold': require('./assets/fonts/OpenSans-Bold.ttf')
    });
    this.setState({ fontLoaded: true });
  }

  render() {
    return this.state.fontLoaded ? <YourComponent /> : <AppLoading />;
  }
}

注意:使用 componentWillMount 可能会抛出错误,因为它不能保证等待我们的 Font.loadAsync 完成。而使用 componentDidMount 不会阻塞应用程序的初始渲染。

0
请使用以下命令升级您的 Expo:

expo upgrade

expo upgrade

Expo版本应该大于36.0.0,否则请尝试使用 npm install expo@36.0.1


-1
如果您正在使用Expo,您应该像这样导入Font和AppLoading:
import { Font, AppLoading } from "expo";

在下一步中,在您的根组件中创建一个常量(不是在组件块中,可能在根组件的顶部),如下所示:
const fetchFonts = () => {
  return Font.loadAsync({
    "open-sans": require("./assets/fonts/OpenSans-Regular.ttf"),
    "open-sans-bold": require("./assets/fonts/OpenSans-Bold.ttf")
  });
};

现在在根组件中:

export default function App() {
  const [fontLoaded, setFontLoaded] = useState(false);
  if (!fontLoaded) {
    return (
      <AppLoading
        startAsync={fetchFonts}
        onFinish={() => {
          setFontLoaded(true);
        }}
      />
    );
  }

  return (
    <Provider store={store}>
      <ShopNavigator />
    </Provider>
  );
}

你的根组件(在我的代码中是App.js)应该最后像这样,以适应:

import React, { useState } from "react";
import { createStore, combineReducers } from "redux";
import { Provider } from "react-redux";
import { Font, AppLoading } from "expo";
import productsReducer from "./store/reducers/products";
import ShopNavigator from "./navigation/ShopNavigator";

const rootReducer = combineReducers({
  products: productsReducer
});

const store = createStore(rootReducer);

const fetchFonts = () => {
  return Font.loadAsync({
    "open-sans": require("./assets/fonts/OpenSans-Regular.ttf"),
    "open-sans-bold": require("./assets/fonts/OpenSans-Bold.ttf")
  });
};

export default function App() {
  const [fontLoaded, setFontLoaded] = useState(false);

  if (!fontLoaded) {
    return (
      <AppLoading
        startAsync={fetchFonts}
        onFinish={() => {
          setFontLoaded(true);
        }}
      />
    );
  }

  return (
    <Provider store={store}>
      <ShopNavigator />
    </Provider>
  );
}

这对我没有用。仍然出现 fontFamily“open-sans-bold”不是系统字体,且未通过Font.loadAsync加载 的错误。 - Ashish

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接