facing problems with styling on react native and achieving a better responsive layout - react-redux

I tried to run my code on various screen sized emulators and the layout of my design varies from device to device. I need help to make the layout more responsive and fixed on different sized screens such as tablets, 3"mobile and 6"mobile.
-----------or connect with us on----------- I want to style this line in better way and that remains the same look on every device
I tried using the dimensions of the screen by defining the width and height using variables, and by describing the values in percentages, but nothing worked.
import React, { Component } from 'react';
import { View,TouchableOpacity, Text, StyleSheet, Image, Dimensions } from 'react-native';
import BacgroundImage from './BackgroundImage';
import Buttons from './Reusable/Button';
const { width: WIDTH } = Dimensions.get('window');
class LaunchScreen extends Component {
render() {
return (
<BacgroundImage>
<View style={styles.logoContainer}>
<Image
source={require('./images/logo.png')}
style={styles.PlaceLogo}
/>
</View>
<View style={styles.Buttons}>
<Buttons style={styles.signupButton}
onPress={() => navigate('Login')}>
<Text style={styles.buttonText}> SIGN UP</Text>
</Buttons>
<Buttons style={styles.loginButton}>
<Text style={styles.buttonText}> SIGN IN</Text>
</Buttons>
</View >
<View style={styles.sepratorView}>
<Text style={styles.sepratorText}>--------- or connect with us on ---------</Text>
</View >
<View style={styles.socialButtonStyle}>
<TouchableOpacity
style={styles.fbstyle}
activeOpacity={0.5}
>
<Image
source={require('./images/facebookicon.png')}
style={styles.iconstyle}
/>
<View
style={styles.sepratorLine}
/>
<Text
style={styles.socialButtonText}
>FACEBOOK</Text>
</TouchableOpacity>
<TouchableOpacity
style={styles.googlestyle}
onPress={this.signIn}
activeOpacity={0.5}
>
<Image
source={require('./images/google.png')}
style={styles.iconstyle}
/>
<View
style={styles.sepratorLine}
/>
<Text style={styles.socialButtonText} >GOOGLE</Text>
</TouchableOpacity>
</View>
</BacgroundImage>
);
};
}
const styles = StyleSheet.create({
logoContainer: {
flex: 1
},
PlaceLogo: {
width: WIDTH - 140,
margin: 75,
resizeMode: 'center',
justifyContent: 'center',
alignItems: 'center',
},
yosoButtons: {
width: WIDTH - 80,
justifyContent:'center',
marginTop:350
},
signupButton: {
height:40,
paddingTop:7,
marginBottom: 15,
},
loginButton: {
height:40,
paddingTop:7,
marginBottom: 15
},
buttonText: {
},
sepratorText: {
textAlign:'center',
fontSize:20,
color: '#b6b7ba',
},
sepratorView: {
flexDirection: 'row',
justifyContent:'center',
alignItems:'center'
},
socialButtonStyle:{
flex:1,
flexDirection:'row',
justifyContent:'center',
alignItems:'center',
margin:5
},
fbstyle:{
flex:1,
flexDirection:'row',
borderColor:'white',
alignItems:'center',
backgroundColor:'#485a96',
borderWidth:1,
borderRadius:35,
height: 40,
marginLeft:15,
marginRight:15
},
googlestyle:{
flex:1,
flexDirection:'row',
alignItems:'center',
backgroundColor:'#dc4e41',
borderWidth:1,
borderRadius:35,
borderColor:'white',
height: 40,
marginRight:15
},
iconstyle:{
resizeMode:'stretch',
height:25,
width:25
},
sepratorLine:{
backgroundColor:'white',
width:2,
height: 40
},
socialButtonText:{
color: '#fff',
flex:1,
textAlign: 'center',
fontSize: 15,
fontWeight: "bold"
}
});
export default LaunchScreen;
I want the layout to remain the same. Both the logo and buttons remain at the same position on every device display.
And I want a better dynamic solution for separator I have used in code
--------------or connect with us on-----------

I got a workaround solution for this problem. I am assigning values using the height and width of the screen to the styling.
import { StyleSheet, Dimensions } from 'react-native';
const { width: WIDTH, height: HEIGHT } = Dimensions.get('window');
SomeText: {
fontSize: HEIGHT / 38,
marginTop: WIDTH / 20,
}

Related

Using FlatList to display custom card elements and need to make them touchable

I need to make the list of items touchable in a flatlist, but have no idea how to make the individual components touchable so i can access the id of that flatlist item. I need to handle the onPress so I can use react navigation 5 to send the users to a different screen.
I'm using an array of data to create a card like component that renders in the flatlist.
how do I make the individual list items touchable?
here's what I'm working with:
import * as React from "react";
import { View, StyleSheet, FlatList, SafeAreaView } from "react-native";
import BigButton from "../components/BigButton.js";
import HomeScreenImage from "../components/HomeScreenImage.js";
import HomeCard from "../components/Card";
const homeOptions = [
{
name: "Beast shedule",
body: "Create and manage your workout shedule",
image: require("../assets/images/DoubleBis.jpg"),
id: "1",
},
{
name: "Pre-Made Workouts",
body: "Use one of our pre-made workouts",
image: require("../assets/images/ChickA.jpg"),
id: "2",
},
{
name: "Statistics",
body: "Analyse your personal statistics",
image: require("../assets/images/WorkoutInProgress.jpg"),
id: "3",
},
{
name: "History",
body: "Keep track of your workout history",
image: require("../assets/images/ChickH.jpg"),
id: "4",
},
];
const HomeScreen = (props) => {
return (
<View style={Styles.containerTop}>
<View>
<HomeScreenImage style={Styles.top} />
<View style={Styles.top}>
<BigButton title="Train & Track" />
</View>
</View>
<SafeAreaView style={Styles.flatListContainer}>
<FlatList
data={homeOptions}
renderItem={({ item }) => {
return <HomeCard info={item} />;
}}
keyExtractor={(homeOption) => homeOption.id}
showsVerticalScrollIndicator={false}
/>
</SafeAreaView>
</View>
);
};
const Styles = StyleSheet.create({
containerTop: {
flex: 1,
backgroundColor: "#3E3636",
},
top: {
flex: 1,
height: "1%",
alignItems: "center",
justifyContent: "center",
},
flatListContainer: {
flex: 1,
},
});
export default HomeScreen;
import React from "react";
import { View, Text, StyleSheet, Dimensions, Image } from "react-native";
const HomeCard = (props) => {
return (
<View style={Styles.container}>
<View style={Styles.cardContainer}>
<Image style={Styles.imageStyle} source={props.info.image} />
<View style={Styles.infoStyle}>
<Text style={Styles.titleStyle}>{props.info.name}</Text>
<Text style={Styles.bodyTextStyle}>{props.info.body}</Text>
</View>
</View>
</View>
);
};
const deviceWidth = Math.round(Dimensions.get("window").width);
const offset = 25;
const radius = 20;
const Styles = StyleSheet.create({
container: {
width: deviceWidth - 20,
marginTop: 20,
},
cardContainer: {
margin: 10,
width: deviceWidth - offset,
backgroundColor: "#000",
height: 200,
borderRadius: radius,
shadowColor: "#000",
shadowOffset: {
width: 5,
height: 5,
},
shadowOpacity: 0.75,
shadowRadius: 5,
elevation: 3,
},
imageStyle: {
height: 130,
width: deviceWidth - 25,
borderTopLeftRadius: radius,
borderTopRightRadius: radius,
opacity: 0.95,
},
titleStyle: {
color: "#F5EDED",
textAlign: "center",
fontSize: 20,
fontWeight: "800",
},
bodyTextStyle: {
fontWeight: "200",
color: "#F5EDED",
textAlign: "center",
},
infoStyle: {
marginHorizontal: 10,
marginVertical: 1,
},
});
export default HomeCard;
You can wrap your card with some touchable component, like TouchableOpacity for example, with naviagtion.navigate('routeName', {params}) function on onPress prop.
const HomeCard = (props) => {
return (
<TouchableOpacity onPress={() => navigation.navigate('ReceiverRoute', {image: props.info image, name: props.info.name })}> ///etc any parameters you want
<View style={Styles.container}>
<View style={Styles.cardContainer}>
<Image style={Styles.imageStyle} source={props.info.image} />
<View style={Styles.infoStyle}>
<Text style={Styles.titleStyle}>{props.info.name}</Text>
<Text style={Styles.bodyTextStyle}>{props.info.body}</Text>
</View>
</View>
</View>
</TouchableOpacity>
);
};
and then you navigate to a component that can receive some params.
For a cleaner example you can look into docs. The main idea is just wrapping your card into some touchable with onpress navigation. For the navigation prop, you can either pass it to your card from parent component, or use useNavigation hook

React-Native | I can't get the bg image to cover

I'm trying to fit my background image to cover the whole app but its not, even though i've tested most of similar threads here so any help is appreciated.
I've made some changes to the original source and added an arrow towards the left edge of the image that i was hoping to have at the edge when i open up the EXPO app on my phone, but i only see a few pixels of the arrow at the left edge.
**app.js**
function HomeScreen() {
return (
<ImageBackground source={require('./assets/bgImage.jpg')} style={styles.bgImage}>
<View>
<Text>Home Screen</Text>
</View>
</ImageBackground>
);
}
bgImage: {
flex: 1,
width: null,
height: null,
resizeMode: 'cover',
justifyContent: 'center',
alignItems: "center"
}
try this :-
import React from 'react';
import { ImageBackground, View, Text } from 'react-native';
const HomeScreen = () => {
return (
<ImageBackground source={require('../assets/apple.jpg')}
style={{
position: "absolute",
top: 0,
left: 0,
bottom: 0,
right: 0,
flex: 1,
alignItems: "center"
}}>
<View style={{
width: '90%',
height: 200,
backgroundColor: "red",
justifyContent: "center",
alignItems: "center",
}}>
<Text>Home Screen</Text>
</View>
</ImageBackground>
);
}
export default HomeScreen;
It is working fine.

React Native Animation Resize

React Native Animation does not scale. Animation is bigger. My code:
import { DangerZone } from 'expo';
const { Lottie } = DangerZone;
Styles:
animationContainer: {
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center',z
},
View:
<Lottie
ref={(animation) => {
this.animation = animation;
}}
resizeMode="contain"
loop={Boolean(true)}
style={{
width: 300,
height: 30,
backgroundColor: '#ccc',
}}
source={this.state.animation}
/>
App screenshot
I don`t know why this does not work. Please help me

How to determine JS bottlenecks in React Native code?

I am adding a React Native Slider component to an existing app, and prefer to utilize its onValueChange prop so that as the user slides the knob left and right, a couple of Text components have their values updated in response to the Slider's current value.
On a first attempt this causes a significant amount of lag after letting go of the slider knob. StackOverflow isn't letting me embed the gif here so I'll leave the link instead: http://imgur.com/sEowpZt
When I comment out onValueChange and use onSlidingComplete instead, there is no lag at all, but the two text components will not have their values updated until the sliding stops, which reduces the effect. My suspicion is that the setState calls inside onValueChange are piling up at a faster rate than than at which they are being processed/completed and it has something to do with other parts of my app. To confirm this, I created a new react native app via react-native init, added that same _renderNameYourPriceModal() to the code, included a button on the screen to open it, and discovered there is no lag at all: http://imgur.com/iZnvDML
How can I determine what is slowing down the setState calls for my existing app? I discovered the React Perf tool and am using it like this to print in the Chrome dev console a summary table.
import Perf from 'react-native/Libraries/Renderer/shims/ReactPerf'
...
componentDidMount() {
setTimeout(() => {
Perf.start()
setTimeout(() => {
Perf.stop()
const measurements = Perf.getLastMeasurements()
Perf.printWasted(measurements)
}, 7000)
}, 1000)
}
According to the Perf docs for printWasted:
printWasted()
Perf.printWasted(measurements)
The most useful part of the profiler.
"Wasted" time is spent on components that didn't actually render
anything, e.g. the render stayed the same, so the DOM wasn't touched.
But I'm not sure how to interpret the results to make the necessary changes. For example, the first four rows of that table when running my app (which has 24 rows in total) looks like this:
I don't know which View the first line, "ItemDetailsScreen > View" inside the Owner > Component column, is referring to because there are 20+ Views on that screen alone. For further context, I'm using React-Navigation and this is a nested screen inside a StackNavigator, although I don't see how updates to this screen's state could cause re-renders in screens further up the hierarchy. Is it necessary to break this screen down further into more custom sub-components so that I override shouldComponentUpdate, or so that the printWasted results tell exactly which areas are at fault?
Here is the function I have for returning the Modal with the Slider inside:
_renderNameYourPriceModal() {
var likelihood = 'Possible'
var lowestVal = 5
var highestVal = 15
if (this.state.nypValue < 6) {
likelihood = 'Nearly Impossible'
} else if (this.state.nypValue < 8) {
likelihood = 'Highly Unlikely'
} else if (this.state.nypValue < 10) {
likelihood = 'Unlikely'
}
return (
<Modal
onRequestClose={() => { this.setState({nypModalVisible: false})}}
animationType={"fade"}
transparent={true}
visible={this.state.nypModalVisible}>
<View style={{paddingTop: 22, height: Dimensions.get('window').height, backgroundColor: 'rgba(252,84,102,0.9)', alignItems: 'center', justifyContent: 'center'}}>
<View
style={{
height: Dimensions.get('window').height * 0.5,
width: Dimensions.get('window').width * 0.9,
backgroundColor: 'white',
borderRadius: 10,
alignItems: 'center'
}}>
<View
style={{flex: 0.8, alignItems: 'center', justifyContent: 'center'}}>
<View style={{flex: 0.25, flexDirection: 'row', width: Dimensions.get('window').width * 0.97, top: -10, alignItems: 'flex-start', justifyContent: 'center'}}>
<View style={{flex: 0.1}}></View>
<View style={{flex: 0.8, alignSelf: 'center', alignItems: 'center', justifyContent: 'center'}}>
<Text style={{fontSize: 23}}>Name Your Price</Text>
</View>
<View style={{flex: 0.1, top: -5, height: 40, alignItems: 'flex-end', justifyContent: 'flex-end'}}>
<TouchableHighlight
underlayColor={'gray'}
style={{height: 40, width: 40, backgroundColor: 'gray', borderRadius: 20, alignItems: 'center', justifyContent: 'center'}}
onPress={() => {
// close
this.setState({nypModalVisible: false})
}}>
<Text style={{fontSize: 25, color: 'white'}}>X</Text>
</TouchableHighlight>
</View>
</View>
<View style={{flex: 0.25, width: Dimensions.get('window').width * 0.8, alignItems: 'center', justifyContent: 'flex-start'}}>
<View style={{flex: 0.5, flexDirection: 'row', alignItems: 'center', justifyContent: 'center'}}>
<View style={{flex: 0.2, alignItems: 'center', justifyContent: 'center'}}>
<Text style={{fontSize: 19}}>${lowestVal.toFixed(2)}</Text>
</View>
<View style={{flex: 0.6, alignItems: 'center', justifyContent: 'center'}}>
<Slider
style={{width: Dimensions.get('window').width * 0.5}}
maximumValue={15}
minimumValue={5}
step={0.5}
value={this.state.nypValue}
// onSlidingComplete={(val) => {
// this.setState({nypValue: val})
// }}
onValueChange={(val) => {
// change value here
this.setState({nypValue: val})
}}
/>
</View>
<View style={{flex: 0.2, alignItems: 'center', justifyContent: 'center'}}>
<Text style={{fontSize: 19}}>${highestVal.toFixed(2)}</Text>
</View>
</View>
<Text>${this.state.nypValue.toFixed(2)}</Text>
<Text>Likelihood: {likelihood}</Text>
</View>
<View style={{flex: 0.5, paddingTop: 20, alignItems: 'center', justifyContent: 'flex-start', paddingHorizontal: 10}}>
<Text style={{textAlign: 'center', top: 25, fontSize: 18}}>Let us know the price you'd like to see this item drop to, and we'll let YOU know when it does!</Text>
</View>
</View>
<View style={{flex: 0.2, alignItems: 'center', justifyContent: 'center'}}>
<TouchableHighlight
style={{height: 50, width: Dimensions.get('window').width * 0.8, alignItems: 'center', justifyContent: 'center', backgroundColor: '#70a8ff', borderRadius: 5}}
underlayColor={'#70a8ff'}
onPress={() => { }}>
<Text style={{fontSize: 20, color: 'white'}}>Set Price Alert</Text>
</TouchableHighlight>
</View>
</View>
</View>
</Modal>
)
}

Text stops wrapping when put on a background Image in react-native

For some reason when I put Text inside Image it stops wrapping. I've tried flexWrap: 'wrap' but it doesn't help.
Here is how it looks like
If I put the Text outside of Image than it works OK.
Here is the code:
class wraptest extends Component {
render() {
return (
<View style={styles.container}>
<Image
source={require('./image.jpg')}
style={styles.image}>
<View style={styles.textContainer}>
<Text style={styles.text}>Text goes here.</Text>
</View>
</Image>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
},
image: {
flex: 1,
resizeMode: 'cover',
justifyContent: 'center',
},
textContainer: {
backgroundColor: 'transparent',
alignItems: 'center',
},
text: {
fontSize: 40,
fontWeight: 'bold'
}
});
I've also pushed full project here https://github.com/OleksandrBezhan/react-native-text-wrap-test
The reason the text wraps when it is outside of the image is because it is a direct child of the "container" style which defines the flex box. Try putting flex: 1 on either the textContainer or text styles.

Resources