I am currently trying to add a custom font to a react native app but after trying almost all answers i could find on SO and on google, it still doesn't work.
i tried to make react native aware of the font by add
"rnpm": {
"assets": [
"./assets/fonts/"
]
},
to the package.json and then running react-native link and also using the re-run commad. But still doesn't work.
Below is the code
app.js
import React, { useEffect } from 'react';
import { StyleSheet, Text, View, Image } from 'react-native';
import imager from './assets/cars.png';
import * as Font from 'expo-font';
export default function App() {
useEffect(() => {
async function loadFont() {
return await Font.loadAsync({
righteous: require('./assets/fonts/Righteous-Regular.ttf'),
});
}
loadFont();
}, []);
return (
<View style={styles.container}>
<Image style={styles.imager} source={imager} />
<Text
style={{
fontSize: 30,
fontWeight: 'bold',
paddingTop: 30,
fontFamily: 'righteous',
}}
>
Request Ride
</Text>
<Text style={{ fontSize: 15, padding: 40, textAlign: 'center' }}>
Request a ride and get picked up by a nearby community driver
</Text>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center',
},
imager: {
width: 200,
height: 200,
shadowColor: 'rgba(0, 0, 0, 0.2)',
shadowRadius: 10,
shadowOpacity: 1,
},
});
I have the font Righteous-Regular.ttf in ./assets/fonts but when i run this code, i get this error
fontFamily "righteous" is not a system font and has not been loaded through 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 Font.loadAsync.
I researched but still can't find the solution to this. Please what could be the issue and how do i go about it?
You are trying to use the font before the font is loaded. You need to do something like this.
import React, { useEffect, useState } from 'react';
import { StyleSheet, Text, View, Image } from 'react-native';
import imager from './assets/cars.png';
import * as Font from 'expo-font';
export default function App() {
// use state for font status.
const [isFontReady, setFontReady] = useState(false)
useEffect(() => {
async function loadFont() {
return await Font.loadAsync({
righteous: require('./assets/fonts/Righteous-Regular.ttf'),
});
}
// after the loading set the font status to true
loadFont().then(() => {
setFontReady(true)
});
}, []);
return (
<View style={styles.container}>
<Image style={styles.imager} source={imager} />
{/* render the text after loading */}
{isFontReady && <Text
style={{
fontSize: 30,
fontWeight: 'bold',
paddingTop: 30,
fontFamily: 'righteous',
}}
>
Request Ride
</Text>}
<Text style={{ fontSize: 15, padding: 40, textAlign: 'center' }}>
Request a ride and get picked up by a nearby community driver
</Text>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center',
},
imager: {
width: 200,
height: 200,
shadowColor: 'rgba(0, 0, 0, 0.2)',
shadowRadius: 10,
shadowOpacity: 1,
},
});
It is up to you to display the element after the font is installed or to display it with a different font before.
Are you using react-native greater than or equal to 0.60? What you have done has worked in my project, but my project is below react-native 0.60. Above 0.60, apparently you have to change react-native.config.js instead of changing package.json. Here is a link to a tutorial that goes over that difference. It is in steop 3 of the tutorial: https://medium.com/#mehran.khan/ultimate-guide-to-use-custom-fonts-in-react-native-77fcdf859cf4
Related
I have two very simple components and the pressables I have in my Start component just won't work, not the navigation or the console.log(), I can't even inspect them with the element inspector... I am using ImageBackground of react native for the first time so i don't know if this has something to do with it? Although, i did try removing it and i still couldn't press anything...
Here is my code for the Start component:
import React from 'react';
import {ImageBackground, Pressable, StyleSheet, Text, View} from 'react-native';
import { normalize } from '../../utils/helper';
import { colors } from '../../utils/styles';
const image = require('../../assets/images/start-page/start-page-background.png');
export default function Start({navigation}) {
const handleStartPress = () => {
console.log('hi');
navigation.navigate('Home');
};
return (
<View style={styles.container}>
<ImageBackground source={image} style={styles.image}>
<Pressable style={styles.startButton} onPress={() => handleStartPress()}>
<Text style={styles.startText}>Έναρξη</Text>
</Pressable>
<View style={styles.footer}>
<Pressable style={[styles.footerPressable, styles.conditions]}><Text style={styles.footerText}>blah</Text></Pressable>
<Text style={styles.code}>blah</Text>
<Pressable style={[styles.footerPressable, styles.policy]} onPress={() => console.log('policy')}><Text style={styles.footerText}>blah</Text></Pressable>
</View>
</ImageBackground>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
},
image: {
flex: 1,
},
startButton: {
backgroundColor: colors.main.blue,
borderRadius: normalize(10),
paddingHorizontal: normalize(40),
paddingVertical: normalize(12),
alignSelf: 'center',
position: 'absolute',
bottom: normalize(180),
},
startText: {
color: 'white',
fontSize: normalize(30),
},
footer: {
paddingVertical: normalize(10),
position: 'absolute',
bottom: normalize(15),
},
conditions: {
borderRightColor: 'black',
borderRightWidth: normalize(1),
paddingLeft: normalize(10),
paddingRight: normalize(10),
},
policy: {
paddingLeft: normalize(10),
//zIndex: 999,
},
footerText: {
fontSize: normalize(16),
lineHeight: normalize(16),
color: 'black',
},
code: {
color: colors.main.blue,
fontWeight: '700',
fontSize: normalize(16),
lineHeight: normalize(16),
borderRightColor: 'black',
borderRightWidth: normalize(1),
paddingHorizontal: normalize(10),
},
});
I ran your code and it works fine. But I don't have any more information on your project (such as your RN version), so I can only make some educated guess.
The non-responsiveness can be caused by the other parts of your application that block your JS thread and prevent the event loop from passing message from the queue to the stack.
To debug this, you can toggle the perfMonitor to see if the JS thread frame rate has dropped to 0. You can also try not to render other elements (e.g. render solely this button in your App.tsx) in your app to see if the issue is gone.
Can someone help me with this Component, i want to make like this, but dont know how this white frames called? Can someone tell me this? And if we press that yellow Touchable Opacity it is showing whole Text, and if we press again it will became smaller!
Thanks in Advance , I am Just new in RN
You can easily create that card with a little bit of CSS.
Below is the sample app which shows you how you can achieve that.
Working Example: Expo Snack
import React, { useState, useEffect } from 'react';
import {
Text,
View,
StyleSheet,
FlatList,
Image,
TouchableOpacity,
} from 'react-native';
import { AntDesign } from '#expo/vector-icons';
import Constants from 'expo-constants';
import { newsFeed } from './news';
export default function App() {
const [news, setNews] = useState(newsFeed);
const showFull = (index) => {
const temp = [...news];
temp[index].toggle = !temp[index].toggle;
setNews(temp);
};
return (
<View style={styles.container}>
<FlatList
data={news}
renderItem={({ item, index }) => (
<View style={styles.card}>
<Text style={styles.title}>{item.title}</Text>
<Text style={styles.paragraph}>
{item.toggle ? item.desc : `${item.desc.substr(0, 100)}...`}
</Text>
{item.toggle && (
<Image source={{ uri: item.img }} style={styles.img} />
)}
<View style={styles.bottomBar}>
<Text style={styles.date}>4/02/2021</Text>
<TouchableOpacity onPress={() => showFull(index)}>
<View style={{ flexDirection: 'row', alignItems: 'center' }}>
<Text style={styles.moreBtn}>
{!item.toggle ? 'More' : 'Less'}
</Text>
<AntDesign
name={item.toggle ? 'up' : 'down'}
size={12}
color="orange"
/>
</View>
</TouchableOpacity>
</View>
</View>
)}
/>
</View>
);
}
const styles = StyleSheet.create({
bottomBar: {
marginVertical: 5,
flexDirection: 'row',
justifyContent: 'space-between',
},
container: {
flex: 1,
justifyContent: 'center',
paddingTop: Constants.statusBarHeight,
backgroundColor: '#ecf0f1',
padding: 8,
},
card: {
padding: 10,
backgroundColor: 'white',
marginVertical: 5,
borderRadius: 10,
},
title: {
marginVertical: 5,
fontSize: 18,
fontWeight: 'bold',
},
img: {
flex: 1,
height: 100,
borderRadius: 10,
marginVertical: 5,
},
paragraph: {
fontSize: 14,
},
date: {
fontSize: 12,
color: 'rgba(21,21,21,0.5)',
},
moreBtn: {
fontSize: 12,
color: 'orange',
marginRight: 10,
},
});
actually this card is not a component you can design it using css and if you want to create a component which you can reuse then you can make one component and reuse it as you want and for this card either you can use your own css or a library called native-base which is
like bootstrap but it is used in react-native
you can read about native base here for more information
https://nativebase.io/
and if you want to create card of your own then make a separate file and make a funcional card component in it
and call it wherever you like
import myCustomCard from './card'
and to use it you use like this in your jsx
<myCustomCard />
and if you want to know more about how to pass props and else you can checkout official docs of the react native here
https://reactnative.dev/docs/getting-started
I am fairly new to React Native and am struggling to get this page to show up when importing it to App.js. It was working by itself, but once I tried to clean things up and put the code into its own file and just call upon it, things went south.
To break things down;
Welcome.js contains the code of a "welcome page" I am trying to create
App.js is the default file created that basically just calls Welcome
and GetStartedButton is just the code of a button that is imported into Welcome but I dont think its necessary to provide.
When running App.js I am not receiving any errors, my screen is just white!
Thank you for any help, I appreciate it more than you know. I apologize for my ignorance!
It wouldnt surprise me if it was just another typo.
I am sure my code is horrible btw! Assuming my styles were an interesting way to do things! Learning...
Welcome.js
import React, { Component } from 'react';
import { StyleSheet, Text, View, Button} from 'react-native';
import GetStarted from './src/components/GetStartedButton';
export default class Welcome extends Component {
render() {
return (
<View style={styles.containerMain}>
<View style={styles.containerClub}>
<Text style={styles.title}>Word</Text>
</View>
<View style={styles.containerCaption}>
<Text style={styles.caption}> Words Words Words </Text>
</View>
<View style={styles.containerBottom}>
<GetStarted text='Get Started' color='#E50061' />
</View>
</View>
);
}
}
const styles = StyleSheet.create({
containerMain: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: 'black',
},
containerClub: {
position: 'absolute',
bottom: 288
},
containerCaption: {
position: 'absolute',
bottom: 250
},
/* To style the button and positioning*/
containerBottom: {
position: 'absolute',
bottom: 100
},
/* To style "Word"*/
title: {
fontSize: 35,
fontWeight: "bold",
},
/* To style "Words Words Words"*/
caption:
{
fontSize: 16
}
}
)
App.js
import React, { Component } from 'react';
import { StyleSheet, Text, View, Button} from 'react-native';
import Welcome from './src/pages/Welcome';
export default class App extends Component {
render() {
return (
<View style={styles.container}>
<Welcome/>
</View>
)
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
}
}
);
GetStartedButton.js
import React, { Component } from 'react';
import { StyleSheet, Text, View, TouchableOpacity } from 'react-native';
const GetStarted = props => {
const content = (
<View style={[styles.button, {backgroundColor: props.color}]}>
<Text style={styles.text}>{props.text}</Text>
</View>
)
return <TouchableOpacity onPress={props.onPress}>{content}</TouchableOpacity>
}
const styles = StyleSheet.create({
button: {
padding: 20,
width: 340,
borderRadius: 8,
alignItems: 'center',
},
text: {
color: 'white',
fontSize: 20,
justifyContent: 'center',
alignItems: 'center',
}
});
export default GetStarted;
The problem is in your Welcome component styles. You colored your texts white, so... it is all white.
const styles = StyleSheet.create({
// (...)
/* To style "word"*/
title: {
color: 'white', // remove it!
fontSize: 35,
fontWeight: "bold",
},
/* To style "words words words"*/
caption:
{
color: 'white', // remove it!
fontSize: 16
}
#edit
Also you did not apply your styles in your App component. It should look like this:
export default class App extends Component {
render() {
return (
<View style={styles.container}>
<Welcome/>
</View>
)
}
}
Try changing backgroundColor to something else other than white like
containerMain: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: 'black'
},
I want to create round shape button for my app which is build upon react native. I had tried the code below but both of them didn't work out for me.
Code snippet 1: <Button title="+" rounded="true"/>
Code snippet 2: addButton: {
width: 20,
height: 20,
borderRadius: 40
}
Basically, you have to style up Views and Touchables to look like the button you want. Here's an example of a circular button component:
import React from 'react';
import { TouchableOpacity, Text, StyleSheet } from 'react-native';
export default ({ title, onPress }) => <TouchableOpacity onPress={onPress} style={styles.button}>
<Text style={styles.title}>{title}</Text>
</TouchableOpacity>
const styles = StyleSheet.create({
button: {
width: 50,
height: 50,
borderRadius: 25,
backgroundColor: 'red',
alignItems: 'center',
justifyContent: 'center',
},
title: {
color: 'white',
}
})
I'm having problems rendering an icon I'm supplying through a prop in a custom component. Here is my custom component:
import React from 'react';
import { View, Image, StyleSheet, Text } from 'react-native';
export class MoreIcon extends React.Component {
render() {
return(
<View style={styles.topViewStyle}>
<View style={styles.circleStyle}>
<Image source={this.props.iconSource} style={styles.iconStyle} />
</View>
<Text style={styles.moreIconText}>{this.props.iconText}</Text>
</View>
);
}
}
const styles = StyleSheet.create({
topViewStyle: {
alignItems: 'center',
justifyContent: 'center',
},
moreIconText: {
fontSize: 12,
fontWeight: 'bold',
color: '#fff',
lineHeight: 1.17,
height: 14,
},
iconStyle: {
width: 30,
height: 30,
},
circleStyle: {
width: 58,
height: 58,
borderRadius: 50,
borderColor: 'rgba(255, 255, 255, 0.3)',
borderWidth: 2,
}
});
The problem is, when I supply a source attribute in the component like this:
<MoreIcon iconText='Home' iconSource={require('../../assets/icons/dashboard.svg')} />
Nothing shows up in the circle, and it looks like this:
What am I doing wrong to where the prop I'm supplying doesn't show up in the MoreIcon tab? (the path is correct fyi)
You'll need to convert your SVGs to be compatible with the react-native-svg library. Luckily, there are a few great examples on the Usage section of the readme.
There's also a great example on Snack
After you've converted them, you'll be able to import them as normal constants.
EDIT:
As per Adam's comment below, using the react-native-svg-uri library now seems like the simpler approach to the SVG problem.