Reputation: 571
I am new in react native and I really get stuck in aligning a two toolbar buttons for two days! I need to put them in the right part of my tool bar using flex. However, I couldn't do that. Here is the code:
export default class ToolbarHorizontal extends Component {
// component prop types
static propTypes = {
items: React.PropTypes.arrayOf(React.PropTypes.shape({
active: React.PropTypes.bool,
name: React.PropTypes.string.isRequired,
imageSourceActive: React.PropTypes.number.isRequired,
imageSourceInactive: React.PropTypes.number.isRequired,
onOpen: PropTypes.func,
})).isRequired,
toolbarActiveItem: React.PropTypes.string.isRequired,
forcedPath: React.PropTypes.bool,
forcedPathImageSource: React.PropTypes.number,
tintColor: React.PropTypes.string,
};
constructor(props) {
super();
this.toolbarActiveIndex = props.items.map((el) => el.name).indexOf(props.toolbarActiveItem);
}
render() {
const { items } = this.props;
let { toolbarActiveItem } = this.props;
let { forcedPath } = this.props;
let { forcedPathImageSource } = this.props;
let { tintColor } = this.props;
tintColor = (tintColor) ? tintColor : '#000'; // default value is black
return (
<View style={styles.container} >
<ScrollView
horizontal={true}
collapsable={true}
showsHorizontalScrollIndicator={false}
showsVerticalScrollIndicator={false}
style={styles.scroller}
>
<View style={styles.componentContainer}>
{ items.map((item, index) => {
let active = (item.active !== undefined) ? item.active : true; // default value is true
if (active) {
return(
<View key={item.id} style={styles.imageContianer}>
{(toolbarActiveItem == item.name) &&
<View style={styles.insideImageContainer}>
<Image
source={item.imageSourceSection}
style={styles.item}
/>
<Text size={20} style={{color:tintColor, paddingRight:10}}>{!forcedPath ? item.description : null}</Text>
</View>
}
</View>
);
}
}
)}
<View style={styles.buttomContainer}>
{ items.map((item, index) => {
//console.log('toolbarActiveItem == item.name:', toolbarActiveItem, '==', item.name);
let active = (item.active !== undefined) ? item.active : true; // default value is true
if (active && (!forcedPath || item.isVisibleWhenForcedPath)) {
return(
<View key={item.id} >
{item.isTouchable && forcedPath && index > 0 &&
<Image
source={forcedPathImageSource}
style={styles.forcedPathImage}
/>
}
{item.isTouchable &&
<TouchableOpacity onPress={() => {
if (!forcedPath) { // when forcedPath, buttons are never touchable
if (toolbarActiveItem != item.name) {
item.onOpen(item.name);
toolbarActiveItem = item.name;
}
else
{ // already on opened page, go back if button is pressed again
this.props.navigation.goBack();
}
}
}}>
{forcedPath &&
<Image
source={(toolbarActiveItem == item.name) ? item.imageSourceForcedPathActive : index > this.toolbarActiveIndex ? item.imageSourceForcedPathTobevisited : item.imageSourceForcedPathVisited}
style={styles.item}
/>
}
{!forcedPath &&
<Image
source={(toolbarActiveItem == item.name) ? item.imageSourceActive : item.imageSourceInactive}
style={styles.item}
/>
}
</TouchableOpacity>
}
</View>
);
}
}
)}
</View>
</View>
</ScrollView>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex:0.16,
flexDirection:'row' ,
//backgroundColor: 'transparent',
},
componentContainer: {
flex:1,
flexDirection:'row',
alignContent:'center',
alignItems: 'center',
},
imageContianer: {
flex:1,
flexDirection:'row',
alignContent:'center',
alignItems:'center',
},
buttomContainer: {
flex:1,
flexDirection:'row',
// backgroundColor: '#9b59b6' ,
},
insideImageContainer: {
flex:1,
alignItems:'center',
flexDirection:'row',
},
scroller: {
marginHorizontal: 0,
marginVertical: 10,
},
item: {
width: 60,
height: 60,
//marginRight: 5,
margin: 2,
},
forcedPathImage: {
flex: 1,
width: 24,
height: 36,
resizeMode: 'contain',
},
});
In fact the problem is that, any changing in flex value doesn't work in insideImageContainer
or imageContianer
. Can you help me to fix this issue.
Thanks in advance.
Upvotes: 0
Views: 839
Reputation: 2624
At a minimum this should be all you need:
Toolbar = () => <View style={styles.container}>
<View style={styles.componentContainer}>
<Text>Icon</Text>
<Text>Title</Text>
</View>
<View style={styles.buttomContainer}>
<Text>Button1</Text>
<Text>Button2</Text>
</View>
</View>
const styles = StyleSheet.create({
container: {
flexDirection: 'row'
},
componentContainer: {
flex: 1,
flexDirection: 'row'
},
buttomContainer: {
flexDirection: 'row'
}
});
The thing to think about when using flex layouts is; which component should take up the spare space? Give that component a flex: 1
property. (And if multiple component should share the same space, split the flex between them).
In this case you don't want your buttomContainer
(typo?) to be any bigger than it needs to be. You want the componentContainer
to grow (flex) as big as it can and push the buttomContainer
to the right.
Upvotes: 2