如何使用 React Navigation 和 Redux 在 Expo 应用程序中加载自定义字体

How to load custom Fonts in an Expo app using React Navigation and Redux

我只是无法使用 Expo、React Natvigation 在现有应用程序中加载自定义字体。我有一个在 core.js 文件中将导航设置为

的应用程序
    import React from "react";
import {Text, View, StyleSheet} from "react-native";
import {NavigationContainer} from "@react-navigation/native";
import {createStackNavigator} from "@react-navigation/stack";
import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
import LoginScreen from "./login.js";
import RegisterScreen from "./register.js";
//import Home from "./home.js";
import PostAJobPage from "./secondTab.js";
import Ionicons from "react-native-vector-icons/Ionicons"
import store from "./store";
import SplashScreen from "./splashscreen";
import Home from "./homeStack.js";
import { Entypo } from '@expo/vector-icons';
import { MaterialCommunityIcons } from '@expo/vector-icons';
import SearchAJobStack from "./jobsearchstack.js";


const Tab = createBottomTabNavigator()

const Tabs = () => {
  return(
    //<NavigationContainer>
      <Tab.Navigator initialRouteName = "home"
        screenOptions = {({route}) => ({
          tabBarIcon : ({focused,color, size}) => {
            let iconName;
            if(route.name == "home") {
              iconName = "ios-home"
              return <Ionicons name = {iconName} color = {color} size = {size}/>
            }
            else if(route.name == "postJob")
            {
              //iconName = "md-settings"
              iconName = "briefcase"
              return <Entypo name = {iconName} color = {color} size = {size}/>
            }
            else if (route.name == "searchJob")
            {
              iconName = "briefcase-search"
              return <MaterialCommunityIcons name = {iconName} size={size} color= {color} />
            }

            //return <Ionicons name = {iconName} color = {color} size = {size}/>
          }
        })}
        tabBarOptions = {{
          style : {
            height : 50
          },
          showLabel : false,
          activeTintColor : "gold"
        }

        }>
        <Tab.Screen name="home" component ={Home}/>
        <Tab.Screen name="postJob" component ={PostAJobPage}/>
        <Tab.Screen name="searchJob" component ={SearchAJobStack}/>
      </Tab.Navigator>
    //</NavigationContainer>
  )
}


const Stack = createStackNavigator()

function Stacks() {
  return(
    <NavigationContainer>
      <Stack.Navigator initialRouteName = "loadingPage">
        <Stack.Screen
          name = "loadingPage"
          component = {SplashScreen}
          options = {{
            headerShown : false
          }}/>

        <Stack.Screen
          name ="Main"
          component = {Tabs}
          options = {{
            headerShown : false,
          }}/>
        <Stack.Screen name= "login"
          component = {LoginScreen}
          options = {{
            title : "Login",
            headerTitleAlign : "left"
          }}/>

        <Stack.Screen name= "register"
          component = {RegisterScreen}
          options = {{
            title : "Register",
            headerTitleAlign : "left",
          }}/>
      </Stack.Navigator>
    </NavigationContainer>
  )
}

export default class core extends React.Component {

  render(){
    return (
      <Stacks/>
    )
  }
}


const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor : "#fff",
    alignItems : "center",
    justifyContent : "center",
  }
})

我正在我的 App.js 中导入这个堆栈,并根据 Expo 中的文档添加了添加自定义字体的代码,但是如果我将 fontFamily: Pacifico 更改为任何屏幕,它都不起作用

我的 app.js 文件是

    import 'react-native-gesture-handler';
import { StatusBar } from 'expo-status-bar';
import React from 'react';
import { StyleSheet, Text, View, Image } from 'react-native';
import Core from "./core.js";
import {Provider} from "react-redux";
import store from "./store.js";
import * as Font from "expo-font";

const customFonts = {
  dancingScript : require("./assets/fonts/DancingScript-Regular.ttf"),
  Pacifico : require("./assets/fonts/Pacifico-Regular.ttf"),
  Inter : require("./assets/fonts/Inter-VariableFont.ttf"),
}


export default class App extends React.Component {
  state = {
    fontsLoaded : false,
  }
  async _loadFontsAsync() {
    await Font.loadAsync(customFonts);
    this.setState({ fontsLoaded: true });
  }

  componentDidMount() {
    this._loadFontsAsync();
  }

  render(){
    if(this.state.fontsLoaded)
    {
      return (
        <Provider store = {store}>
          
          <Core/>

        </Provider>
      );
    }
    else {
      return(
        <View style= {styles.container}>
          <Image source = {require("./ajax-loader.gif")}/>
        </View>
      )
    }

  }

}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#fff',
    alignItems: 'center',
    justifyContent: 'center',
    //fontFamily : "dancingScript",
  },
});

这是在 expo 应用程序中加载字体的方法 在应用程序的入口点编写代码,主要是 App.js

  import { useFonts } from "expo-font"; 

   const [fontsLoaded] = useFonts({
        // Axiforma: require("./assets/fonts/Axiforma-Black.ttf"),
        // BlackItalic: require("./assets/fonts/Axiforma-BlackItalic.ttf"),
        Bold: require("./assets/fonts/Axiforma-Bold.ttf"),
        // BoldItalic: require("./assets/fonts/Axiforma-BoldItalic.ttf"),
        // Book: require("./assets/fonts/Axiforma-Book.ttf"),
        // BookItalic: require("./assets/fonts/Axiforma-BookItalic.ttf"),
        ExtraBold: require("./assets/fonts/Axiforma-ExtraBold.ttf"),
        // ExtraBoldItalic: require("./assets/fonts/Axiforma-ExtraBoldItalic.ttf"),
        // Heavy: require("./assets/fonts/Axiforma-Heavy.ttf"),
        // HeavyItalic: require("./assets/fonts/Axiforma-HeavyItalic.ttf"),
        // Italic: require("./assets/fonts/Axiforma-Italic.ttf"),
        Light: require("./assets/fonts/Axiforma-Light.ttf"),
        // LightItalic: require("./assets/fonts/Axiforma-LightItalic.ttf"),
        Medium: require("./assets/fonts/Axiforma-Medium.ttf"),
        // MediumItalic: require("./assets/fonts/Axiforma-MediumItalic.ttf"),
        Regular: require("./assets/fonts/Axiforma-Regular.ttf"),
        SemiBold: require("./assets/fonts/Axiforma-SemiBold.ttf"),
        // SemiBoldItalic: require("./assets/fonts/Axiforma-SemiBoldItalic.ttf"),
        Thin: require("./assets/fonts/Axiforma-Thin.ttf"),
        // ThinItalic: require("./assets/fonts/Axiforma-ThinItalic.ttf"),
      });
      if (!fontsLoaded) return <AppLoading />;

我个人觉得这是加载自定义字体的更好方法。我在我所有的项目中都使用这种方法。 loadFonts 创建一个名为 hooks 的文件夹,您的 App.js 位于

然后,安装 expo-app-loading & expo-font

然后在 hooks 文件夹中创建一个名为 useFonts.js

的文件

里面useFonts.js这样写

import * as Font from "expo-font";

export default useFonts = async () => {
   await Font.loadAsync({
      "Pacifico" : require("./assets/fonts/Pacifico-Regular.ttf"),
      // All other fonts here
    });
};.

现在在你的App.js中这样写

import * as Font from 'expo-font';
import AppLoading from 'expo-app-loading';
import React, { useState } from 'react';

import useFonts from './hooks/useFonts';

export default function App() {
  const [IsReady, SetIsReady] = useState(false);

  const LoadFonts = async () => {
    await useFonts();
  };

  if (!IsReady) {
    return (
      <AppLoading
        startAsync={LoadFonts}
        onFinish={() => SetIsReady(true)}
        onError={() => {}}
      />
    );
  }

  return <View styles={styles.container}>{/* Code Here */}</View>;
}

注意:以上解决方案适用于 Function 个组件。

对于Class Component,你可以这样做

Working Example Here

import React from 'react';
import { StyleSheet, Text, View, Image } from 'react-native';

import useFonts from './hooks/useFonts';

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

  async _loadFontsAsync() {
    await useFonts();
    this.setState({ fontsLoaded: true });
  }

  componentDidMount() {
    this._loadFontsAsync();
  }

  render() {
    if (this.state.fontsLoaded) {
      return (
        <View style={styles.container}>
          <Text>Fonts Loaded</Text>
          <Text style={{ fontFamily: 'Helvetica' }}>Helvetica Text</Text>
          <Text>Normal Text</Text>
        </View>
      );
    } else {
      return (
        <View style={styles.container}>
          <Image
            source={{
              uri:
                'https://landerapp.com/blog/wp-content/uploads/2018/06/1_FFP1bisztXseQFbZ-WQedw-1.png',
            }}
            style={{ width: '100%', height: '100%' }}
          />
        </View>
      );
    }
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#fff',
    alignItems: 'center',
    justifyContent: 'center',
    //fontFamily : "dancingScript",
  },
});

使用@expo-google-fonts

从终端转到项目根目录并键入以安装所需的字体,例如:

expo install @expo-google-fonts/ubuntu

explo cli会安装所有ubuntu字体作为一个节点模块,在路径里面查看./node_modules/@expo-google-fonts/ubuntu,所有字体都在那里。

现在,从这个字体系列中导入你想要的钩子和字体样式,如下所示:

import { useFonts, Ubuntu_400Regular, Ubuntu_500Medium, Ubuntu_700Bold } from '@expo-google-fonts/ubuntu';

然后,使用钩子将它们加载到您的应用程序中:

let [fontsReady,fontsError] = useFonts({Ubuntu_400Regular, Ubuntu_500Medium, Ubuntu_700Bold});
当字体可以使用时

fontsReady 将为真,如果应用程序无法加载,fontsError 将有错误原因字体。

要等待字体准备就绪,请使用 expo-app-loading 模块并执行如下操作:

if (!fontsReady) return <AppLoading/>;

要选择您希望在项目中安装的字体,请访问 https://directory.vercel.app/ ,这将以简单的方式显示所有 Google 字体和导入命令。不要忘记包含 useFonts 挂钩。