JibZ
JibZ

Reputation: 143

How to apply expo react-native custom font to the entire container

I tried to load a custom font for my react-native app that i'm developing with expo but i don't know how to load a font in a simplier way for the whole screen container.

Currently i used the offical expo doc: Expo Custom Font Documentation

They said to use a Font.loadAsync() function and then use the this.state.fontLoaded? like this:

    <View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
  {
    this.state.fontLoaded ? (
      <Text style={{ fontFamily: 'open-sans-bold', fontSize: 56 }}>
        Hello, world!
      </Text>
    ) : null
  }
</View>

but did it exist a solution for applying the font on a container for example? I think it's not easy to e forced to surround EACH Text elements with the same function...

Currently the font is loading on ONE text element, but i would like to be able to easily use my font on a container, or many Text elements at once.

Here is my code:

    state = {
        fontLoaded: false,
    };

    async componentDidMount() {
        await Font.loadAsync({
            'ubuntu-medium': require('../assets/fonts/Ubuntu-Medium.ttf'),
        });
        this.setState({ fontLoaded: true });
    }
    render() {
        return (
            <View style={styles.main_container}>

                <View style={styles.inner_main_container}>

                    <View style={styles.top_links_container}>
                        <View style={styles.profile_and_arrow_container}>
                            <Icon
                                name='arrow-back'
                                color='white'
                                style={styles.icon} />
                            {
                                this.state.fontLoaded ? (
                                    <Text style={styles.top_links_profile}>Profil</Text>
                                ) : null
                            }
                        </View>
                        <View style={styles.profile_edit_container}>
                            <Text style={styles.top_links_edit}>Editer</Text>
                        </View>
                    </View>
                    <View style={styles.profile_avatar_container}>
                        <Avatar
                            rounded
                            size='xlarge'
                            source={{ uri: 'https://randomuser.me/api/portraits/men/27.jpg' }}>
                        </Avatar>
                    </View>
                    <View style={styles.profile_infos_container}>
                        {
                            this.state.fontLoaded ? (
                                <Text style={styles.user_name}> Dupont Jean </Text>
                            ) : null
                        }
                        <Text style={styles.user_title}> CSD - Product Owner </Text>
                    </View>
                    <View style={styles.subprofile_infos_container}>

                        <View style={styles.user_experience}>
                            <Text>Experience </Text>
                            <Text style={styles.user_experience_years}> 7ans</Text>
                        </View>

                        <View style={styles.user_grade}>
                            <Text>Grade </Text>
                            <Text style={styles.user_grade_letter}> D </Text>
                        </View>
                    </View>
                    <View numberOfLines={6}>
                        <Text style={styles.user_bio}> Lorem Ipsum is simply dummy text of the printing and
                                    typesetting industry. Lorem Ipsum has been the industry's standard…</Text>
                    </View>
                    <View>
                        <Text style={styles.user_bio_see_more_link}> Voir plus</Text>
                    </View>
                    <Divider style={styles.divider} />
                    <View style={styles.bottom_container}>
                        <View style={styles.bottom_cm_text_info_container}>
                            <Text style={styles.bottom_cm_text_info}>Carrière Manager d'Evelyne</Text>
                            <Text style={styles.bottom_cm_text_user_name}>Jerôme Durand</Text>
                        </View>
                        <View style={styles.bottom_cm_avatar}>
                            <Avatar
                                rounded
                                size='small'
                                source={{ uri: 'https://randomuser.me/api/portraits/men/27.jpg' }}
                            />
                            <Icon
                                name='right'
                                type='antdesign'
                                color='grey'
                                onPress={() => console.log('hello button cm view')}
                            />
                        </View>
                    </View>
                </View>
            </View>
        );
    }
}

Upvotes: 4

Views: 3779

Answers (3)

Sehaj Singh Bindra
Sehaj Singh Bindra

Reputation: 26

    // CustomText.js
import React from 'react';
import { Text as RNText, StyleSheet } from 'react-native';

const CustomText = ({ children, style, fontSize, ...restProps }) => {
  return (
    <RNText style={[styles.text, { fontSize }, style]} {...restProps}>
      {children}
    </RNText>
  );
};

const styles = StyleSheet.create({
  text: {
    fontFamily: 'Quicksand', // Replace with your custom font family
    // Add more common styles as needed
  },
});

export default CustomText;

You can follow this approach though for functional components!!

Upvotes: 0

Greg T
Greg T

Reputation: 3404

The documentation says there is no way to set the font across the entire app.

The recommended way to use consistent fonts and sizes across your application is to create a component MyAppText that includes them and use this component across your app. You can also use this component to make more specific components like MyAppHeaderText for other kinds of text.

More info and example on the Expo <Text> docs:

https://docs.expo.io/versions/latest/react-native/text/

--

As far as loading custom font files, I'd recommend using SplashScreen.preventAutoHide() to keep the splash screen visible while you load the fonts in a function via <AppLoading>. This provides a smooth loading experience, and ensures your fonts are available when the rest of your app is eventually rendered.

Upvotes: 0

JibZ
JibZ

Reputation: 143

Finally i found a nicely working solution.

I had to create a custom component like this one:

1. Create a custom component TextCustom.js for example and put this into:

import React from 'react'
import { Text, StyleSheet, View, ActivityIndicator } from 'react-native'
import * as Font from 'expo-font'

export default class TextCustom extends React.Component {
    constructor(props) {
        super(props)

        this.state = {
            loading: true,
        }
    }

    async componentWillMount() {
        await Font.loadAsync({
            'Ubuntu': require('./../assets/fonts/Ubuntu-Medium.ttf')
        })
        this.setState({ loading: false })
    }

    render() {
        if (this.state.loading) {
            return <ActivityIndicator/>
        }
            return (
                <View>
                    <Text style={[styles.defaultStyle, this.props.style]}>
                        {this.props.children}
                    </Text>
                </View>
            )
    }
}

const styles = StyleSheet.create({
    defaultStyle: {
        fontFamily: 'Ubuntu'
    },
})

Don't forget to import Font from Expo (for people using Expo)

2. in the component you want to use the custom font, simply import and use the newly created component:

import TextCustom from './TextCustom'
import TextBoldCustom from './TextBoldCustom'  (if you want to use a Bold or italic font)

and use it:

<View>
    <TextCustom style={styles.info_welcome}>Bonjour</TextCustom>
</View>

Upvotes: 5

Related Questions