Hello i was following along a tutorial and it was going fine, until the tutor used react-native-paper ProgressBar in his project, I wrote exactly same but it was not visible, I found the documentation and plugged it, still not visible.
What am i Doing wrong?
import {View, StyleSheet, Text} from 'react-native' ;
import { ProgressBar, Colors } from 'react-native-paper';
import CountDown from '../comps/CountDown.js' ;
const Timer = ({task}) => {
return (
<View style={styles.container}>
<CountDown />
<Text style={styles.text}> Focusing On:</Text>
<Text style={[styles.text, styles.textBold]}> {task} </Text>
<ProgressBar progress={0.4} color='#5E84E2' style={styles.progress}/>
</View>
) ;
}
const styles = StyleSheet.create({
container : {
flex: 1,
width: 100,
alignItems: 'center' ,
justifyContent: 'center',
paddingTop: 40,
},
text: {
// flex: 0.5,
color: 'white'
},
textBold: {
fontWeight: 'bold' ,
// borderColor: 'white',
// borderWidth: 1,
// borderStyle: 'solid' ,
},
progress: {
height: 10,
// borderColor: 'white',
// borderWidth: 1,
// borderStyle: 'solid' ,
}
}) ;
export default Timer ;
Also, If i were to Give border to the progressBar, it appears but keep on increasing in width even when width is more than the viewport width. I dont know what is happening
The problem here is when you use alignItems the children components need to have a fixed width, your progress bar doesnet have a fixed width.
You will have to provide a with in the styles.
progress: {
height: 10,
width:50
}
Based on documentation default value for width is
auto (default value) React Native calculates the width/height for the
element based on its content, whether that is other children, text, or
an image.
Better have a value for width which will solve your issue.
A responsive solution
Currently ProgressBar doesn't support the flex styling system.
If someone is also looking to make the width equal to 100% if it's parrent component, there is a good recommended solution provided here.
Just set the width to undefined:
progress: {
height: 10,
width:undefined
}
e.g.
<View style={{ flex: 2, other flex styles }}>
<ProgressBar progress={0.5} color="white" style={{ height: 5, width: undefined }} />
</View>
Related
I am working on a react native project. I want to provide shadow to view. But it was spreading away like this.
But what I want is:
I got the answer that I need to add background color here: https://taketo.site/solved
And that actually solves my problem but only when I add background color from the stylesheet. But my problem is that I want to get the background color from props as everytime the view is rendered, it won't have the same bg color, it would be different. But when I try to provide bg color from props, it again gives shadow like in the first image. Here's my code:
component file:
import React from 'react';
import { View } from 'react-native';
import { styles } from './styles';
class ShadowCard extends React.Component {
constructor(props) {
super(props);
}
render() {
return (
<View
style={[
styles.card,
{
width: this.props.width,
height: this.props.height,
backgroundColor: this.props.backgroundColor,
},
]}>
{this.props.children}
</View>
);
}
}
export default ShadowCard;
stylesheet file:
import { StyleSheet } from 'react-native';
export const styles = StyleSheet.create({
card: {
shadowColor: '#000',
shadowOffset: { width: 0, height: 2 },
shadowOpacity: 0.5,
shadowRadius: 2,
elevation: 10,
borderRadius: 12,
margin: 12,
},
});
So what should I do so that I can take the bg color from props and the shadow shows up like in second image?
You can probably do something like this ->
Wrap your current cart View in another View with overflow hidden to prevent the shadow to show up above the box and then add some padding bottom to show the shadow underneath the box for android, and for ios, keep the shadowOffset as it currently is
<View style={{ overflow: 'hidden', paddingBottom: 60 }}>
<View
style={{
width: this.props.width,
height: this.props.height,
backgroundColor: this.props.backgroundColor,
shadowOffset: { width: 2, height: 6 },
shadowRadius: 6,
shadowOpacity: 0.2,
elevation: 15,
}}>
{this.props.children}
</View>
</View>
I have the following code:
import React from "react";
import { StyleSheet, View } from "react-native";
function App() {
return (
<View style={styles.container}>
<View style={styles.row_1}>
<View style={styles.square} />
</View>
<View style={styles.row_2}>
<View style={styles.square} />
</View>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1
},
row_1: {
flex: 1,
backgroundColor: "red",
alignItems: "center",
padding: 10
},
row_2: {
flex: 5,
backgroundColor: "blue",
alignItems: "center",
//flexDirection: 'row',
padding: 10
},
square: {
flex: 1,
aspectRatio: 1,
backgroundColor: "white"
}
});
export default App;
I'm trying to insert a white square in the center of the rows, without knowing a priori the height and the width of the rows. In the example, on a 4:3 phone, the first row is larger then higher and the second row higher than larger.
The square in the first row is correct, but the square in the second row exceeds the margins. I can manually set flexDirection: 'row' in the row_2 to achieve the expected result, but just because I know the container is higher than larger. How can I achieve the same result, without specifing the flex direction?
Sandbox here
Not exactly sure what the final result you're looking for, but for something responsive like this I would consider using a dynamic unit on width/height properties on your squares like viewport units -- vw, vh, vmin, vmax.
Alternatively you can get the viewport dimensions in pixels:
//e.g.
document.documentElement.clientWidth
document.documentElement.clientHeight
//or including scrollbar:
window.innerWidth
window.innerWidth
Then use a css styles library like emotion use the viewport dimensions in your styles.
i have an about component that just render two text component, this is the code:
class about extends Component {
render() {
return (
<>
<View style = {this.styles.container}>
<Text style = {this.styles.text}>Hi</Text>
<Text style = {this.styles.text}>A very simple notebloc.</Text>
</View>
</>
);
}
styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: "center",
marginTop: - Math.round(Dimensions.get("window").height * 0.5) / 2,
flexDirection: "column"
},
text: {
fontSize: 25,
fontFamily: "serif",
textAlign: "center",
color: "#1E90FF",
}
})
}
pertty simple, the problem now, is that I want them with FontSize: 25 but when I taste it in real devices, in some of them the second text is separated, gonna post some screen so you can see the issue:
this is how I want it works in all devices:
but in some devices I get this:
how can I solve this? I set the fontSize to 24 and I think it will work in all devices, but when its in 25, it doesnt, something to add, the first image is a device that the width is bigger than the second one, so I think the width isnt the problem
To solve that, try to use react-native-size-matters to scale the font size no matter the device pixel density.
For example
fontSize: moderateScale(24, 0.3)
I have a screen that has several components, some with relative positioning and some with absolute. When the screen is opened, the absolute positioned components don't go all the way to their final correct position, or size. They appear on the screen, but in the wrong spot and size. Only by changing a state with a button press, do the components finish rendering. Here's a simplified version of the screen below:
The screenshot on the left has the absolutely positioned menu icon (3 horizontal lines at the top right), not all the way in its correct position yet. The screen on the right shows the icon in its final correct position, only after I changed a state by pressing a touchable region.
Here is the code:
import React, {Component} from 'react';
import {View, Text, StyleSheet, Animated, Image, Dimensions, TouchableWithoutFeedback} from 'react-native';
import colors from '../config/colors';
import Icon from 'react-native-vector-icons/Ionicons';
import Orientation from 'react-native-orientation-locker';
const w = (Dimensions.get('window').width);
const h = (Dimensions.get('window').height);
const r = h / w;
if (r > 1.9) {
mission_font_heading = 14;
mission_font = 12;
check_dimension = 14;
name_font = 10;
} else {
mission_font_heading = 12;
mission_font = 10;
check_dimension = 12;
name_font = 8;
}
class how_to_play9_screen extends Component {
constructor (props) {
super(props);
this.state = {
test: 0, //changing this state "fixes" the component's position
}
}
componentDidMount() {
Orientation.lockToPortrait();
}
openMenu() {}
showMission() {
this.setState({test: 2}); //this changes the state
}
render() {
return (
<View>
<Image
style={styles.backgroundImage}
source={require('../images/Background.png')}
>
</Image>
<View style={{alignItems: 'center'}}>
<TouchableWithoutFeedback onPress={() => this.showMission()}>
<View style={styles.missionContainer}>
<Text style={styles.missionTitleText}>
MISSION TITLE
</Text>
<Text style={styles.text}>
(X VP)
</Text>
<View style={{flexDirection: 'row'}}>
<Image
style={styles.checkBox}
source={require('../images/Checkbox.jpg')}
/>
<Text style={styles.missionReqText}>
Mission Requirement 1
</Text>
</View>
</View>
</TouchableWithoutFeedback>
</View>
// below is the absolute positioned component
<View
style={{
position: 'absolute',
top: 5,
right: 5,
}}
>
<TouchableWithoutFeedback
onPress={() => this.openMenu()}
>
<Icon
name='ios-menu'
size={(Dimensions.get('window').width) * .08}
color={colors.JBDarkTeal}
/>
</TouchableWithoutFeedback>
</View>
</View>
);
}
}
const styles = StyleSheet.create({
backgroundImage: {
width: (Dimensions.get('window').height) * .65,
height: (Dimensions.get('window').height) * 1.3,
position: 'absolute',
left: 0,
top: 0,
},
missionContainer: {
backgroundColor: colors.JBTealTrans,
borderWidth: 2,
borderColor: colors.JBTan,
marginVertical: 10,
paddingVertical: 3,
paddingRight: 5,
width: '80%',
},
missionTitleText: {
fontSize: mission_font_heading,
textAlign: 'center',
color: colors.JBTan,
marginVertical: 3,
marginHorizontal: 5,
},
text: {
fontSize: mission_font,
textAlign: 'center',
color: colors.JBTan,
marginVertical: 3,
},
missionReqText: {
fontSize: 12,
color: colors.JBTan,
marginVertical: 3,
marginLeft: 5,
marginRight: 5,
},
checkBox: {
width: check_dimension,
height: check_dimension,
marginVertical: 3,
marginLeft: 5,
},
})
export default how_to_play9_screen;
I want the icon and any other absolute positioned components to go straight to their final position upon screen opening.
Edit: I should also mention that the previous screen locks the orientation to landscape, and this screen locks it back to portrait. I found that if I load this screen from a different screen that is already in portrait, then this one renders correctly, so it seems that it doesn't like me changing the orientation.
The position is not the problem, the problem is size of <Icon /> try to using number instad Dimensions calc, or make this calc on componentDidMount or render
Whenever I put a string of more than 5 characters inside a element, the last one is not rendered.
Here's my code and the outputted string.
const Header = () => {
const { textStyles, viewStyles } = styles;
return (
<View style={viewStyles}>
<Text style={textStyles}>Albums</Text>
</View>
);
};
const styles = {
viewStyles: {
backgroundColor: '#F8F8F8',
alignItems: 'center',
justifyContent: 'center',
height: 60,
paddingTop: 15,
shadowColor: '#000',
shadowOffset: { width: 0, height: 2 },
elevation: 2
},
textStyles: {
fontSize: 20
},
};
Outputted string:
Album
If I change the string inside the Text element to something like 'Albums!', the output will be Albums. It always show n-1 characters.
I tested your code buddy Its working fine
import React from 'react';
import { StyleSheet, Text, View } from 'react-native';
const Header = () => {
const { textStyles, viewStyles } = styles;
return (
<View style={viewStyles}>
<Text style={textStyles}>Albums!!!!</Text>
</View>
);
};
export default class App extends React.Component {
render() {
return (
<View>
<Header></Header>
</View>
);
}
}
const styles = StyleSheet.create({
viewStyles: {
backgroundColor: '#F8F8F8',
alignItems: 'center',
justifyContent: 'center',
height: 60,
paddingTop: 15,
shadowColor: '#000',
shadowOffset: { width: 0, height: 2 },
elevation: 2
},
textStyles: {
fontSize: 20
},
});
Here is the output
I experienced the same issue on my OnePlus 6.
I fixed it by using textAlign: "center" instead of using alignItems: "center".
I propose changing your styles to:
const styles = {
viewStyles: {
backgroundColor: '#F8F8F8',
justifyContent: 'center',
height: 60,
paddingTop: 15,
shadowColor: '#000',
shadowOffset: { width: 0, height: 2 },
elevation: 2
},
textStyles: {
fontSize: 20,
textAlign: "center"
},
};
Please add all components fontFamily: "" style just like this with empty value. Example:
<Text style={{color:'red', fontFamily: "", fontSize:20}}> Hasan Rıza UZUNER </Text>
Manually applying a font may fix this issue
Here's how using expo / Here's how in vanilla react native
If you don't feel like following those links, here's a quick rundown:
1. Acquire and add your font to your project
Make a new folder (eg. assets/fonts/) to hold your font's ttf files, here's a link to roboto
Copy your .ttf files directly into the directory you created (eg. assets/fonts/Roboto-Regular.ttf)
2. Link your fonts
Add rnpm asset configuration to your package.json (using your new folder from above, our example is assets/fonts/ but you can use whatever folder you want.
"rnpm": {
"assets": [
"./assets/fonts/"
]
}
Execute react-native link from your terminal
3. Use your font
From our example above we're using Roboto, replace Roboto with whatever font family you have downloaded. If you're on a mac and don't know the font family you can use the font book.app default app to find the name.
<Text style={{ fontFamily: 'Roboto' }}>Some Text Here</Text>
I think you made just need to add width to either the text or the parent view
May be you can wrap you inside and give width of '100%' to both tags.
<View style={{flex:1,alignItems:'center', justifyContent:'center', width:'100%'}}>
<Text style={{width:'100%', fontWeight:'bold', fontSize: 12, textAlign:'center'}}> Whatever the text you want to write here..!!</Text>
</View>
Don't know if it is still relevant.
I solved this issue by adding width to text element