I am new to React Native and have been struggling for a couple of days now with my layout overflowing the container after rotating the device and then rotating it back. What seems to happen is when I rotate the device from horizontal to vertical the text in the body takes up more height. When rotating back to horizontal the height seems to be sticking for the body rather than resizing like it should. I am testing it in Android Studio. I have tried two different emulators with the same results.
This is what it looks like when I first load the page:
I rotate it vertical and get this:
When I rotate it back I get the following. Notice that the start button is missing in the first box.
Here is my code:
<ScrollView style={SiteStyle.mainContent} contentContainerStyle={SiteStyle.mainContentContainer}>
<View style={SiteStyle.cardGroup}>
<View style={SiteStyle.homeCardContainer}>
<Card
title={
<View style={SiteStyle.homeCardHeader}>
<View style={{flexDirection: 'row', flexWrap: 'wrap'}}>
<PSIcon color='#fff' name='currency-scale' size={24} style={{marginRight: 10}}/><Text style={SiteStyle.homeCardTitle}>Topic 1</Text>
</View>
</View>}
containerStyle={SiteStyle.homeCard}>
<View style={SiteStyle.homeCardBody}>
<Text style={SiteStyle.homeCardBodyText}>
Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged.
</Text>
</View>
<View style={SiteStyle.homeCardFooter}>
<TouchableOpacity onPress={() => navigate('Pricing', {})}>
<Text style={SiteStyle.homeCardFooterText}>
START <PSIcon name='controls-chevron-right'/>
</Text>
</TouchableOpacity>
</View>
</Card>
</View>
<View style={SiteStyle.homeCardContainer}>
<Card title={
<View style={SiteStyle.homeCardHeader}>
<View style={{flexDirection: 'row', flexWrap: 'wrap'}}>
<PSIcon color='#fff' name='chart-chart' size={24} style={{marginRight: 10}} /><Text style={SiteStyle.homeCardTitle}>Topic 2</Text>
</View>
</View>} containerStyle={SiteStyle.homeCard}>
<View style={SiteStyle.homeCardBody}>
<Text style={SiteStyle.homeCardBodyText}>
Lorem Ipsum is simply dummy text of the printing and typesetting industry.
</Text>
</View>
<View style={SiteStyle.homeCardFooter}>
<TouchableOpacity onPress={() => navigate('TrendsAndAnalytics', {})}>
<Text style={SiteStyle.homeCardFooterText}>
START <PSIcon name='controls-chevron-right'/>
</Text>
</TouchableOpacity>
</View>
</Card>
</View>
<View style={SiteStyle.homeCardContainer}>
<Card title={
<View style={SiteStyle.homeCardHeader}>
<View style={{flexDirection: 'row', flexWrap: 'wrap'}}>
<PSIcon color='#fff' name='currency-scale' size={24} style={{marginRight: 10}}/><Text style={SiteStyle.homeCardTitle}>Topic 3</Text>
</View>
</View>} containerStyle={SiteStyle.homeCard}>
<View style={SiteStyle.homeCardBody}>
<Text style={SiteStyle.homeCardBodyText}>
Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book.
</Text>
</View>
<View style={SiteStyle.homeCardFooter}>
<TouchableOpacity onPress={() => navigate('MacroEconomics', {})}>
<Text style={SiteStyle.homeCardFooterText}>
START <PSIcon name='controls-chevron-right' />
</Text>
</TouchableOpacity>
</View>
</Card>
</View>
</View>
</ScrollView>
These are the relevant styles:
mainContentContainer: {
paddingTop: 25,
alignItems: 'flex-start',
backgroundColor: "red"
},
cardGroup: {
flexDirection: 'row',
flex: -1
},
homeCardContainer: {
flex: 1,
backgroundColor: 'blue',
flexDirection: 'column',
},
homeCard: {
flex: 1,
padding: 0,
marginTop: 0,
marginHorizontal: 10,
flexDirection: 'row',
backgroundColor: 'green',
height: '100%'
},
homeCardHeader: {
backgroundColor: '#e0ab24',
flex: -1,
flexBasis: 55,
height: 55,
justifyContent: 'center',
paddingLeft: 20,
paddingTop: 0
},
homeCardTitle: {
color: '#ffffff',
fontSize: 22,
marginLeft: 0,
paddingRight: 0,
textAlign: 'left'
},
homeCardBody: {
flexDirection: 'column',
flex: 1,
paddingLeft: 25,
paddingRight: 25,
paddingTop: 25,
paddingBottom: 25,
backgroundColor: 'yellow'
},
homeCardBodyText: {
fontSize: 16,
backgroundColor: 'pink'
},
homeCardFooter: {
flex: 0,
flexBasis: 44,
justifyContent: 'center',
height: 44,
borderTopColor: '#d3d3d3',
borderTopWidth: 1,
backgroundColor: 'gray',
},
homeCardFooterText: {
paddingLeft: 25,
paddingRight: 25,
color: '#ebad49',
fontSize: 18
},
For anyone interested I found the solution. On the container I want to resize based upon content (homeCardBody) I needed to change flex: 1 to flexGrow: 1, removing the stand alone word flex completely. Once doing this the component sized correctly and maintained correct sizing upon rotation.
Your homeCardFooter style has flex: 0, on it which looks like it might be the cause of this. From the docs: "When flex is 0, the component is sized according to width and height and it is inflexible." I would give homeCardFooter a width of 100%, or give it a flex value greater than zero. Try giving it flex: .3 to see if that prevents your start button from being hidden/having a height of zero.
Related
<View style={{flexDirection: 'row', backgroundColor: 'yellow'}}>
<TouchableOpacity
style={{
padding: 5,
borderWidth: 1,
backgroundColor: 'pink',
}}>
<Text style={styles.goldenText}>Cancel</Text>
</TouchableOpacity>
<TouchableOpacity
style={{
padding: 5,
borderWidth: 1,
backgroundColor: 'pink',
}}>
<Text style={styles.goldenText}>Cancel</Text>
</TouchableOpacity>
</View>
My parent view has flexDirection="row". I need my child components to take the entire width of parent view dynamically.
ie, if there are 3 child components i need it to be divided equally, in the yellow region without margin between them. Tried width, flex etc
but nothing seems to be working..
Have a try by flex: 1 in the parent style.
For Example:
<View style={{flex: 1, flexDirection: 'row', backgroundColor: 'yellow'}}>
I fixed this issue.
After a bit of research I found that , when parent view has flexDirection:"row"
the flex inside the touchableopacity(child component) doesn't works.
I replaced TouchabllOpacity with pressable and now flex gets applied properly.
<View
style={{
flexDirection: 'row',
backgroundColor: 'yellow',
}}>
<Pressable
style={{
padding: 5,
borderWidth: 1,
backgroundColor: 'pink',
flex: 1,
}}>
<Text style={styles.goldenText}>Cancel</Text>
</Pressable>
<Pressable
style={{
padding: 5,
borderWidth: 1,
backgroundColor: 'pink',
flex: 1,
}}>
<Text style={styles.goldenText}>Cancel</Text>
</Pressable>
<Pressable
style={{
padding: 5,
borderWidth: 1,
backgroundColor: 'pink',
flex: 1,
}}>
<Text style={styles.goldenText}>Cancel</Text>
</Pressable>
</View>
I am trying to design below layout in react native.
I am not able to draw horizontal line as shown above.
Some how I have drawn but margin on the right is not being applied
Code
<View style={{ flexDirection: 'row' }}>
<Text style={styles.text}>
Search
</Text>
<View style={styles.viewStyleForLine1}></View>
</View>
Style
viewStyleForLine1: {
borderWidth: 1,
borderColor: '#cc0000',
alignSelf: 'stretch',
marginLeft: 5,
marginRight: 5,
width:"100%"
},
More edit on centering the content
Here is how my View is
<View style={{ flexDirection: 'row' }}>
<Text style={styles.text}>
Search</Text>
<View style={styles.viewStyleForLine1}></View>
</View>
Style
text: {
marginTop: 16,
fontSize: 30,
fontWeight: 'bold',
color: '#cc0000',
marginLeft: 15
},
viewStyleForLine1: {
borderBottomWidth: 1,
borderColor: '#cc0000',
marginLeft: 5,
alignItems:"center",
marginRight: 15,
alignSelf:"center",
flex:1
},
What modification I should do?
you can change the style width: "100%" to "flex:1". you want the right view to occupy the rest of width, then the "flex:1" means the rest of width belongs to it.it has a weight. the percentage you have to use in both components. the more tips about UI adapter you can read this article
viewStyleForLine1: {
borderWidth: 1,
borderColor: '#cc0000',
alignSelf: 'stretch',
marginLeft: 5,
marginRight: 5,
flex:1
},
I'm using React-Native.I'm living trouble with Picker component on Android. I use Picker from Native-Base Library.
Here is my Picker code with it's parent view.
<View style={{height: 40, marginTop: 20}}>
<Label style={{fontWeight: 'bold', color: '#d7d7d7'}}>Phone</Label>
<View style={{flexDirection: 'row',width: '100%',borderWidth: 1, borderColor: '#d7d7d7', height: 40}}>
<View style={{flexDirection: 'row',width: '30%', height: '100%' ,backgroundColor: '#d7d7d7', alignItems: 'center'}}>
<Picker style={{width: 100, height: '100%', marginLeft: 5}}
selectedValue={this.state.selectedCountry}
onValueChange={(value)=>this.onCodeChanged(value)}>
<Picker.Item label={<Text style={{alignItems: 'center', flexDirection: 'row'}}>
<Thumbnail square style={{width: 30, height: 20, marginTop: 5}} source={require('../assets/+90.png')}/> +90</Text>} value="+90"/>
<Picker.Item label={<Text style={{alignItems: 'center', flexDirection: 'row'}}>
<Thumbnail square style={{width: 30, height: 20, marginTop: 5}} source={require('../assets/+44.png')}/> +44</Text>} value="+44"/>
<Picker.Item label={<Text style={{alignItems: 'center', flexDirection: 'row'}}>
<Thumbnail square style={{width: 30, height: 20, marginTop: 5}} source={require('../assets/+1.png')}/> +1</Text>} value="+1"/>
</Picker>
</View>
<Input keyboardType={'numeric'} style={{width: '70%', height: '100%'}} value={this.state.phone} onChangeText={(value)=>this.setState({phone: value},()=>console.log("Phone State: ", this.state.phone))}/>
</View>
</View>
Here is how Picker looks like in IOS
And here is the error screen I get on android.
It seems the problem is Picker.Item's Labelcontent. When I changed the content of label from Text to usual, ordinary string, it works fine on android, as well. But, somehow I need the flag and code together in Picker.Item
I hope there is someone who faced & handled this issue before.
I have recently started using React-Native, and one of the main issues I have been struggling with is the layout design.
I have a "Card" like component that holds some information about movies. Components like Image and Text that are big goes out of the bounds of the card and does not respect the padding and margins provided.
Here is the JSX code:
<View style={[styles.container, styles.card]}>
<View style={{alignSelf: 'stretch', flexDirection: 'row', padding: 10}}>
<Image style={{height: 50, width: 50, borderRadius: 25}}
source={require('../../img/sarah-avatar.png.jpeg')}/>
<View style={{flexDirection: 'column', marginTop: 5, marginLeft: 15}}>
<Text style={styles.title}>{ this.state.movie.name }</Text>
<Text style={{color: 'gray'}}>{ moment(this.state.movie.releaseDate).format('DD/MM/YYYY') }</Text>
</View>
</View>
<View style={{alignItems: 'center'}}>
<!-- THIS IMAGE DOES NOT RESPECT THE CARD BOUNDS -->
<Image style={{height: 220, resizeMode: 'center'}}
source={require('../../img/advance-card-bttf.png')}/>
<View style={{flexWrap: 'wrap', marginTop: 10, marginBottom: 20}}>
<Text style={{color: 'gray', fontSize: 14}}>
{ this.state.movie.summary }
</Text>
</View>
</View>
<View style={{flexDirection: 'row', flex: 1}}>
<Button onPress={this.onLikeClick.bind(this)}>
<View style={{flexDirection: 'row'}}>
<Icon name="thumbs-up" size={18} color="#007aff" />
<Text style={{color: '#007aff', marginLeft: 5}}>{ this.state.movie.likes } Likes</Text>
</View>
</Button>
<View style={{width: 20}} />
<Button onPress={this.onCommentClick.bind(this)}>
<View style={{flexDirection: 'row'}}>
<Icon name="comment" size={18} color="#007aff" />
<Text style={{color: '#007aff', marginLeft: 5}}>{ this.state.movie.comments.length } Comments</Text>
</View>
</Button>
</View>
<Comments comments={this.state.movie.comments }
showComments={ this.state.showComments }
handler={this.handler} />
</View>
const styles = StyleSheet.create({
card: {
backgroundColor: "#fff",
borderRadius: 2,
shadowColor: "#000000",
shadowOpacity: 0.3,
shadowRadius: 1,
shadowOffset: {
height: 1,
width: 0.3,
},
padding: 10,
flexWrap: 'wrap'
},
container: {
flex: 1,
backgroundColor: '#F5FCFF',
margin: 5
},
title: {
fontSize: 20,
backgroundColor: 'transparent'
},
button: {
marginRight: 10
}
});
And the comments component JSX code:
<View style={{flexDirection: 'column'}}>
{
this.props.comments.map((comment, index) => {
return (
<View key={index} style={{flexDirection: 'row', marginTop: 20}}>
<Image style={{height: 50, width: 50, borderRadius: 25}}
source={require('../../img/avatar-ts-woody.png')}/>
<View style={{flexDirection: 'column', marginLeft: 15, marginTop: 3}}>
<Text style={{fontSize: 18}}>{ comment.name }</Text>
<!-- THE COMMENT CONTENT GOES OUTSIDE OF THE CARD -->
<Text style={{color: 'gray'}}>{ comment.content }</Text>
</View>
</View>
)
})
}
<TextInput placeholder="Leave a comment"
value={this.state.commentContent}
onChangeText={(text) => this.setState({commentContent : text})}
onSubmitEditing={this.onCommentEntered.bind(this)}
style={{height: 40, marginTop: 18}} />
</View>
Here you can see that the cover image seems like it's out of the card:
In here each comment might start correctly inside the card, but will go outside of the bounds when text is too long:
I am currently using React-Native for an Android Project. I have been trying to make a TextInput field with an icon beside the field. However, for some reasons, I notice that the flexDirection: 'row' is not working if the TextInput is one of its child component. The whole view of the one that I apply the style will automatically disappear. This is a snippet of how my code looks like:
<View style={{flex: 1, alignItems: 'center', justifyContent: 'center'}}>
<View style={{flexDirection: 'row'}}>
<Image
style={{height: 30, width: 30}}
source={require('./images/email-white.png')}
/>
<TextInput
style={{height: 40}}
underlineColorAndroid={'transparent'}
placeholder={'E-mail'}
placeholderTextColor={'white'}
onChangeText={(data) => this.setState({ username: data })} />
</View>
</View>
I also tried to wrap both component inside each individual view, but the problem still persists. Is there anyone who knows how to solve this? or anyone can confirm that this is a bug?
Your code with a small modification worked fine for me. The only thing I did was adding a width to the TextInput resulting in the icon being beside the text-input.
Working code:
<View style={{flex: 1, alignItems: 'center', justifyContent: 'center'}}>
<View style={{flexDirection: 'row'}}>
<Image
style={{height: 30, width: 30}}
source={require('./images/email-white.png')}
/>
<TextInput
style={{height: 40, width: 300}}
underlineColorAndroid={'transparent'}
placeholder={'E-mail'}
placeholderTextColor={'white'}
onChangeText={(data) => this.setState({ username: data })} />
</View>
</View>
I had the same problem when I was building example code from the book Mastering React Native
The code had enclosed a TextInput field in a View with a flexDirection: 'row' and the child TextInput field was not accessible. Only the TextInput border was visible. After playing around with some of the suggestions on this page I found something that worked.
If the container view has a flexDirection: 'row'. Please make sure to add a flex: 1 into your textfield input. The image flex does not seem necessary. As soon as I added the flex: 1 to the styles.input sheet, the TextInput was accessible.
The following code works for me :
<View style={globalStyles.COMMON_STYLES.pageContainer}>
<View style={styles.search}>
<Image
style={{height: 30, width: 30}}
source={require('../../images/email-white.png')}/>
<TextInput
style={styles.input}
onChangeText={text => this.setState({ searchText: text})}
value={this.state.searchText}
placeholder={'Search'}
placeholderTextColor={globalStyles.MUTED_COLOR}/>
</View>
</View>
Local Styles :
const styles = StyleSheet.create({
input: {
flex: 1,
height: 35,
color: globalStyles.TEXT_COLOR,
borderColor: globalStyles.MUTED_COLOR,
backgroundColor: globalStyles.BG_COLOR
},
search: {
borderColor: globalStyles.MUTED_COLOR,
flexDirection: 'row',
alignItems: 'center',
borderRadius: 5,
borderWidth: 1,
// marginTop: 10,
// marginBottom: 5
}
})
Global Styles (styles/global)
export const COMMON_STYLES = StyleSheet.create({
pageContainer: {
backgroundColor: BG_COLOR,
flex: 1,
marginTop: 0,
paddingTop: 20,
marginBottom: 48,
marginHorizontal: 10,
paddingHorizontal: 0
},
text: {
color: TEXT_COLOR,
fontFamily: 'Helvetica Neue'
}
});
Hopefully this provides assistance to you guys. It took me a long time get something this simple working.
Try closing your Image tag...
<Image style={{width:30, height: 30}} source={require('./icon.png')} />
Also, add some dimensions to your TextInput...
<TextInput style={{height: 40, borderColor: 'gray', borderWidth: 1}} />
You might also need to set flex: 0 on the image and flex: 1 on the TextInput