I have the following code:
renderActionButtons(actionButtons){
let actionButtonsContent = actionButtons.map((button, i) => {
return <TouchableHighlight key={i} onPress={() => {this.updateConversation(button);}} style={globalStyle.actionButton} underlayColor='#f1f1f1'>
<View key={i}>
<Text style= {globalStyle.actionButtonText}>{ button }</Text>
</View>
</TouchableHighlight>
})
return actionButtonsContent
}
renderConversations(){
let conversationContent = this.state.conversationArray.map((convObj, i) => {
return <View key={i} style={[globalStyle.conversationContainer,globalStyle.shadow,convObj.directionClass]}>
<Text style= {[globalStyle.conversationText,convObj.directionTextClass]}>{ convObj.text }</Text>
<View style= {globalStyle.actionButtonsContainer}>
{ this.renderActionButtons(convObj.actionButtons) }
</View>
</View>
})
return conversationContent
}
This is to render the following view:
I'm trying to wrap those pills inside the white container.
Following are the styles I have used:
conversationContainer:{
maxWidth:310,
backgroundColor: 'white',
borderBottomRightRadius: 10,
borderTopRightRadius: 10,
borderBottomLeftRadius: 0,
borderTopLeftRadius: 10,
padding: 10,
marginTop: 10
},
actionButtonsContainer:{
flex:1,
flexDirection: 'row',
paddingTop: 10
},
actionButton:{
backgroundColor:primaryRed,
borderRadius:30,
padding: 7,
marginRight: 10
},
actionButtonText:{
color:'white',
fontSize:12,
alignSelf: 'center'
},
How can I wrap the child Elements inside the parent element so that it doesn't overflow like show in picture ?
With flexbox, you have the flexWrap property, it defines whether the flex items are forced in a single line or can be wrapped. By default it's set to nowrap. Set it to wrap:
actionButtonsContainer:{
flex:1,
flexDirection: 'row',
flexWrap: 'wrap',
paddingTop: 10
},
Related
I have written following code but my flex under 'titleContainer' is not working.
export const Focus = () => {
return (
<View style={styles.container}>
<View style={styles.titleContainer}>
<Text style={styles.title}>What would you like to focus on?</Text>
<TextInput />
</View>
</View>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#43840',
},
titleContainer: {
flex: 0.5,
padding: 16,
justifyContent: 'center',
backgroundColor: '#559974',
},
title: {
color: 'white',
fontWeight: 'bold',
fontSize: 15,
},
});
Please see the screen shot. The green background should cover half of the screen.
Its resolved now!
Actually this component was getting displayed conditionally. There was an issue with that condition. I have fixed that and everything worked.
Flex in RN only take interger value
In case you want titleContainer take 50% size of container by using flex, This is how you can achieve that.
You need another view the take the same flex value with titleContainer, so titleContainer and that dump view will take 50% size of parent view each
export const Focus = () => {
return (
<View style={styles.container}>
<View style={styles.titleContainer}>
<Text style={styles.title}>What would you like to focus on?</Text>
<TextInput />
</View>
<View style={{flex: 1}} />
</View>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#43840',
},
titleContainer: {
flex: 1,
padding: 16,
justifyContent: 'center',
backgroundColor: '#559974',
},
title: {
color: 'white',
fontWeight: 'bold',
fontSize: 15,
},
});
To use flex property on child tag your parent tag needs to have a display: "flex" property on it.
container: {
display: 'flex',
flexDirection: 'column',
flex: 1,
backgroundColor: '#43840',
},
In my React Native app, I try to create a simple divider line. As stated here for example, I created an empty View and added the corresponding styling to it.
Now here's the thing: the divider line is not showing up with this code:
<View style={styles.divider}>
<Text></Text>
</View>
... Stylesheet:
divider: {
borderBottomWidth: 1,
borderLeftColor: 'white',
},
But If I add some text lines, it shows up:
<View style={styles.divider}>
<Text>testtest</Text>
</View>
... Stylesheet:
divider: {
borderBottomWidth: 1,
borderLeftColor: 'white',
},
Now here is the code context.
<View style={styles.containerWholePage}>
<View style={styles.containerUpper}>
<Text style={styles.mainText}>Here is a sample text</Text>
</View>
<View style={styles.containerLower}>
<View style={styles.containerText}>
<Text>TEST</Text>
<Text>Example 3</Text>
<Text>18:00 - 20:00</Text>
</View>
<View style={styles.divider}>
<Text>testtest</Text>
</View>
<View style={styles.containerText}>
<Text>TEST2</Text>
<Text>Example 3b</Text>
<Text>18:00 - 19:00</Text>
</View>
</View>
</View>
...
const styles = StyleSheet.create({
containerWholePage: {
alignItems: 'center',
flex: 1,
},
divider: {
borderBottomWidth: 1,
borderBottomColor: 'white',
},
containerLower: {
alignItems: 'center',
alignSelf: 'stretch',
backgroundColor: '#1E2928',
flex: 6,
justifyContent: 'space-around',
},
containerText: {
alignItems: 'center',
backgroundColor: '#1E2928',
},
containerUpper: {
alignItems: 'center',
alignSelf: 'stretch',
backgroundColor: 'white',
flex: 3,
},
});
Maybe you have an idea how to make the bottom line appear without having to write text?
Just do like this:
<View style={styles.divider}/>
...
divider: {
borderBottomWidth: 1,
borderBottomColor: 'white',
width:"100%"
},
Because the width is flexible to it's content, so if nothing in it, it doesn't have width. So that if you set the width, the View will have width setting as you want.
Code sandbox
Basically that should work I just tested it in sandbox and adding a
<View style={{borderBottomWidth: 1}} >
<Text></Text>
</View>
worked perfect for me.. maybe add a {" "} between the Text tags.
you can also try:
<View style={styles.divider}/>
divider: {
borderBottomWidth: 1,
borderBottomColor: 'white',
alignSelf:"stretch"
},
but I prefer just using width: "100%"
I have a component with TextInput and another component which is called CompanyAddress. Each company can have many addresses, therefore I have to have "plus" button.
There are container styles
const AppStyles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: "#ffffff",
alignItems: "center",
justifyContent: "center"
},
inputStyle: {
height: 40,
width: '80%',
borderColor: '#28c9d9',
textAlign: 'center',
borderWidth: 1,
marginBottom: 20,
fontSize: 16
}
});
there is main component
<KeyboardAvoidingView behavior="padding" style={AppStyles.container}>
<TextInput
autoCompleteType="name"
placeholder="organization"
maxLength={30}
style={AppStyles.inputStyle}
onChangeText={(text) => { this.setState({name: text})} }
/>
<CompanyAddress/>
</KeyboardAvoidingView>
and there is CompanyAddress
class CompanyAddress extends React.Component<any, any> {
render() {
return (
<View style={styles.container}>
<TextInput
autoCompleteType="name"
placeholder="address"
maxLength={30}
style={[AppStyles.inputStyle, styles.textInput]}
/>
<AntDesign style={styles.plus} name="plus" size={24} color="black" />
</View>
);
}
}
const styles = StyleSheet.create({
container: {
width: '100%',
flexDirection: 'row'
},
textInput: {
width: '70%',
},
plus: {
width: '30%'
}
});
but my CompanyAddress now looks like that
but I want to change styles for achieve that
you can add justifyContent:center to the container and for the children alignSelf:Center
ex:
<View style={{justifyContent : center,flexDirection:row}}>
<View style={{alignSelf:Center}}><View>
<View style={{alignSelf:Center}}><View>
</View>
Lets assume that we have those react native styles:
var styles = StyleSheet.create({
parentView:{
width: 400,
height:150
},
containerView:{
flex:1,
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'center',
backgroundColor:'black'
},
child1:{
backgroundColor: 'red',
alignSelf: 'flex-start'
},
child2: {
backgroundColor: 'yellow'
}
}
and that we have this render function:
render: function(){
return(
<View style={styles.parentView}>
<View style={styles.containerView}>
<Text style={styles.child1}>Child1</Text>
<Text style={styles.child2}>Child2</Text>
</View>
</View>
);
}
This code produces this image:
but what I want to achieve is this image:
VERY VERY IMPORTANT: I want child2 to be TOTALLY centered within the containerView, and not a bit far to the right because of the space that child1 occupies.
How can I achieve that in react-native?*
p.s.: Keep in mind that this will run on many resolutions (many screens with different aspect ratios) thus, it cannot be set in an absolute way that would result on it only working on "some" screens but not on others.
not sure if this is the best way to do it, but it works for me
render() {
return(
<View style={styles.parentView}>
<View style={styles.containerView}>
<View style={styles.rowContainer}>
<View style={styles.rowItem}>
<Text style={styles.child1}>Child1</Text>
</View>
<View style={styles.rowItem}>
<Text style={styles.child2}>Child2</Text>
</View>
</View>
</View>
</View>
);
const styles = StyleSheet.create({
parentView:{
width: 400,
height:150
},
containerView:{
flex:1,
flexDirection: 'row',
alignItems: 'center',
backgroundColor:'black'
},
rowContainer: {
flex: 1,
flexDirection: 'column',
},
rowItem:{
flex: 1
},
child1:{
backgroundColor: 'red',
position: 'absolute',
},
child2: {
alignSelf: 'center',
backgroundColor: 'yellow'
}
});
I'm looking to set the position of the date on the right of my row.
Here is the code:
const styles = StyleSheet.create({
container: {
flex: 1,
marginTop: 64,
},
row: {
flexDirection: 'row',
alignItems: 'center',
margin: 5,
backgroundColor: 'green',
},
horizontalAlign: {
flexDirection: 'row',
alignItems: 'center',
backgroundColor: 'red',
},
rowTitle: {
fontFamily: 'Helvetica',
fontSize: 17,
marginLeft: 10,
flex: 1,
textAlign:'center'
},
rowDate: {
textAlign: 'right',
},
rowText: {
fontFamily: 'Helvetica',
fontSize: 17,
marginLeft: 10,
},
rowImage: {
width: 35,
height: 35,
borderRadius: 17.5,
},
});
renderRow(rowData, sectionID, rowID, _highlightRow) {
return (
<TouchableHighlight onPress={ () => { this.rowPressed(rowData.recordID || null); }}>
<View style={styles.row}>
<Image source={ require('myImage.png') } style={styles.rowImage} />
<View>
<View style={styles.horizontalAlign}>
<Text style={styles.rowTitle}>{rowData.title}</Text>
<Text style={styles.rowDate}>{rowData.date}</Text>
</View>
<Text style={styles.rowText}>{rowData.text}</Text>
</View>
</View>
</TouchableHighlight>
);
}
render() {
return (
<View style={styles.container}>
<ListView
dataSource={this.state.dataSource}
renderRow={::this.renderRow}
/>
</View>
);
}
A screenshot:
Any suggestion?
You need to add a flex:1 property to the view containing the rowData.title and rowData.date. I've set up an example with your data here.
<View style={{flex:1}}>
<View style={styles.horizontalAlign}>
<Text style={styles.rowTitle}>{rowData.title}</Text>
<Text style={styles.rowDate}>{rowData.date}</Text>
</View>
<Text style={styles.rowText}>{rowData.text}</Text>
</View>
https://rnplay.org/apps/mWO0LQ
I'm not familiar with React, but in standard CSS, apply margin-left: auto to the date item.
You could also apply justify-content: space-between to the flex container which would align both flex items on opposite edges.
(These solutions assume that the line on which the flex items exist is free to extend the full width of the container.)