简体   繁体   中英

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

I just can not load custom fonts in an existing app using Expo, React Natvigation. I have an app that has Navigations set up in a core.js file as

    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",
  }
})

I am importing this stacks in my App.js and have added the code to add custom fonts according to the Docs in Expo but if I change fontFamily: Pacifico to any of the screens it doesnot work

My app.js file is

    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",
  },
});

I personally feel this is a better way to load custom fonts. I use this method in all my projects. To loadFonts create a folder called hooks where your App.js is located

Then, Install expo-app-loading & expo-font

Then inside hooks folder create a file called useFonts.js

Inside useFonts.js write like this

import * as Font from "expo-font";

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

Now in your App.js write like this

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>;
}

Note: The above solution was for Function components.

For Class Component , you can do something like this

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",
  },
});

this is how you can load your fonts in an expo app write the code in the entry point of your app which is mainly 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 />;

Use @expo-google-fonts

Go to the project root from the terminal and type to install the font that wish, example:

expo install @expo-google-fonts/ubuntu

The explo cli will install all ubuntu fonts as a node module, look inside the path./node_modules/@expo-google-fonts/ubuntu, all fonts are there.

Now, import the hook and the font styles that you wish from this font family, like this:

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

Then, load them inside your app using the hook:

let [fontsReady,fontsError] = useFonts({Ubuntu_400Regular, Ubuntu_500Medium, Ubuntu_700Bold});

fontsReady will be true when the fonts are ready to use and the fontsError will has the error reason if the app could not load the fonts.

To wait the fonts be ready, use expo-app-loading module and do something like this:

if (!fontsReady) return <AppLoading/>;

To choose the fonts that you wish to install on your project, visit https://directory.vercel.app/ , this will show all Google fonts and the import cmd in an easy way. Do not forget to include the useFonts hook.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM