Reputation: 620
As , I developed a react native using physical device with screen size of 6 inch , it looked great and then when I tested with 5.5 it some what great , as still few components got spreader ! Then I tried with 4.3 inch , omg most of the components went beyond the screen . Then I googled , and found few packages which helps with screen size , it corrected the prop with 5.5 but still the prop persist at 4.3 inch !
I have converted most of the width and height as % , only padding is valued with int .
How to make the ui, responsively ! And one of my majore doubt is, I have created a top level View component with flex :1 and width and height with screen size. Even though , how come the sir goes beyond in small screen mobiles ?
As it should consider the screen size only bcoz , I have declared the width and height of screen by fetching the screen size. So every other components should be inside these values , but how comes it goes beyond ?
Please guide me with this , thanks in advance !
Update: Here is the code.
import React, { Component } from 'react';
import { View, Image, Dimensions } from 'react-native';
import { connect } from 'react-redux';
import { oneDayPlanSelected, monthlyPlanSelected } from '../../actions';
import { Text, Button, Card } from 'react-native-elements';
import {widthPercentageToDP as wp, heightPercentageToDP as hp} from
'react-
native-responsive-screen';
const windowW= Dimensions.get('window').width;
const windowH = Dimensions.get('window').height;
class PlanSelection extends Component {
onMonthlyPlanButtonPressed() {
this.props.monthlyPlanSelected();
}
onOneDayPlanButtonPressed(){
this.props.oneDayPlanSelected();
}
render () {
const cowMilk = require('../../Images/cow_plan.png');
const buffaloMilk = require('../../Images/buffalo_plan.png');
return (
<View style={styles.containerStyle}>
<View style={styles.topContainerStyle}>
<View style={styles.topBlueBoxContainer}>
<Text h4 style={styles.introTextStyle}>
Now, Choose how you wish to buy ? We have two
plans.
</Text>
<View style={styles.imageContainerStyle}>
<Image
source={ this.props.milkType === 'Cow Milk' ?
cowMilk : buffaloMilk }
style={styles.topContainerImageStyle}
/>
<View style={styles.choosePlanTextContainerStyle}>
<Text h4 style={styles.choosePlanTextStyle}>
Choose your plan.
</Text>
</View>
</View>
</View>
</View>
<View style={{flexDirection:'row', justifyContent: 'space-
evenly'}}>
<View>
<Card
containerStyle={{borderRadius: 5, width: windowW/2.2
}}
>
<View style={{ alignItems: 'center' }}>
<View style={{flexDirection: 'row'}}>
<Text style=
{styles.planNumberTextStyle}>1</Text>
<Text style={{ fontSize: 12, top: 40,
fontWeight: 'bold' }}>Day</Text>
</View>
<View style={{ padding: 0 }}>
<Text style={styles.planDescpStyle}>Buy One
day plan, by which we will deliver Cow Milk by Today.</Text>
</View>
<View style={{ padding: 0 }}>
<Text style={styles.planNameTextStyle}>One Day
Plan</Text>
</View>
</View>
<Button
backgroundColor='#2980b9'
rightIcon={{name: 'arrow-forward'}}
title='Buy'
raised
onPress=
{this.onOneDayPlanButtonPressed.bind(this)}
/>
</Card>
</View>
<View>
<Card
containerStyle={{borderRadius: 5, width: windowW/2.2
}}
>
<View style={{ alignItems: 'center' }}>
<View style={{flexDirection: 'row'}}>
<Text style=
{styles.planNumberTextStyle}>30</Text>
<Text style={{ fontSize: 12, top: 40,
fontWeight: 'bold' }}>Day's</Text>
</View>
<View style={{ padding: 0 }}>
<Text style={styles.planDescpStyle}>We
have various monthly plans, Check In for more info</Text>
</View>
<View style={{ padding: 0 }}>
<Text style=
{styles.planNameTextStyle}>Monthly Plan</Text>
</View>
</View>
<Button
backgroundColor='#2980b9'
rightIcon={{name: 'arrow-forward'}}
title='Buy'
raised
onPress=
{this.onMonthlyPlanButtonPressed.bind(this)}
/>
</Card>
</View>
</View>
<View style={styles.noteContainerStyle}>
<Text style={styles.noteTextStyle}>We are excited ! Kindly
select any one plan, and note that Monthly plan has various sub plans. For
more info kindly choose the plan. </Text>
</View>
</View>
);
}
}
const styles = {
containerStyle: {
flex: 1,
height: windowH,
width: windowW,
},
topBlueBoxContainer:{
backgroundColor: '#f0ffff',
height: windowH/1.7,
justifyContent: 'space-evenly',
},
imageContainerStyle: {
alignSelf: 'center'
},
topContainerImageStyle: {
resizeMode: 'contain',
height: windowH/3
},
introTextStyle: {
fontSize: 20,
paddingBottom: windowH/28,
paddingLeft: windowW/8,
},
choosePlanTextStyle: {
fontSize: 22
},
choosePlanTextContainerStyle:{
alignSelf: 'center',
padding: 15
},
planNameTextStyle: {
fontSize: 16,
fontWeight: 'bold'
},
planNumberTextStyle: {
fontSize: 50,
fontWeight: 'bold',
color: '#37BBE1'
},
planDescpStyle: {
fontSize: 13,
flexWrap: 'wrap',
textAlign: 'center'
},
noteTextStyle: {
fontSize: 10,
color: '#b2bec3'
},
noteContainerStyle: {
paddingTop: windowH/30,
paddingLeft: windowW/25,
paddingRight: windowW/10,
bottom: windowW/22
}
};
const mapStateToProps = state => {
return {
milkType: state.order.milktype
};
};
export default connect(mapStateToProps,
{oneDayPlanSelected,monthlyPlanSelected})(PlanSelection);
Ui in 4.3 Inch Screen :
Ui in 6 Inch screen :
Check the bottom of the screen, button components and few words are been overflowed. And i have been using react native elements for button and card, is this because of that ? Any idea and Suggestion ?
Upvotes: 4
Views: 18608
Reputation: 1
useWindowDimentions() will be useful there https://reactnative.dev/docs/usewindowdimensions
Upvotes: 0
Reputation: 3686
Ok adding answer (Sorry for the delay) I've found and fixed some problems with your styling
In your root view
containerStyle: {
flex: 1, //This already tells that it should fill all space available, no need for width or height
//height: windowH,
//width: windowW,
},
topContainerStyle doesn't exist in your code so i have no idea
UPDATE 2 hours later...
i've rebuilt the whole ui only to demonstrate how flex should be used, keep in mind that i have cut some text out, that's because if you need the text to be shown it needs to be short, or be wrapped in a scrollview . I've replaced the card, since it was giving some problems with flex , just style a view, give it some padding and you have a custom card.
I wanted to use react-native-size-matters but i've spent too much time in this , however, a quick tip is , if you can rotate the phone, and the ui is not completelly trash, you have a great UI! c:
https://snack.expo.io/rygco3J74
You can even implement your own button... i personally don't use react-native-elements because i like to do things my own ;) check the expo and try rotating the phone, you can even add a listener to the rotation and change the font size according to the rotation.
Upvotes: 0
Reputation: 3686
My way is to use a combination of flex [to fill what i want no matter the size], with the aspectRatio property [to have the same aspect ratio in every screen no matter the size], and the library react-native-size-matters [to have the size units scaled accordint to the screen], so far, the ui is responsive to smartphones and tablets c:. Oh, and never, NEVER i use absolute values, ite makes the ui , as you said , overflow [xd].
Another neat tricks is just not use the height or width property, since they accomodate to their children. I have a bar, with width:'100%'
, and inside i have a text component with fontSize:moderateScale(30)
[react-native-size-matters], and also padding:moderateScale(5)
. That simple setup renders the same bar , with responsive ui [it´s normal on small screens and bigger on big screens] 7u7
Upvotes: 0
Reputation: 1661
Although Dimensions like Harshit mentioned is an option, i don't like it, because when user changes direction from landscape to portrait for example, the values are not updated accordingly and you have an ugly ui.
I prefer setting it up with flex, and make sure that views with lots of content are ScrollViews(for smaller devices).
Also for horizontal space, if it is essential, you can set like 320-340 fixed dp for mobiles, and 820-840 fixed dp for tablets on container view..
Upvotes: 0
Reputation: 2524
try using flex
properties (flex
, flexDirection
) and alignment with alignItems
& jsutifyContent
alongwith desired margins & paddings.
Upvotes: 0
Reputation: 5089
You should not use % for providing width and height for components instead you should use Dimensions to get the width and height of the screen and then adjust the component style accordingly like marginTop, marginBottom, etc
const { width, height } = Dimensions.get('window');
OR,
you can do something like this
const windowW= Dimensions.get('window').width
const windowH = Dimensions.get('window').height
and use this as dims:{ height:windowH/2, width: windowW}
Moreover, you can adjust the width and height using windowW/2-30 etc..
Make sure to import Dimensions using-
import {StyleSheet, Dimensions} from 'react-native';
Upvotes: 1