How to add a custom component to createMaterialTopTabNavigator tab bar
It is not so difficult to create a custom tab bar component, below is a mimimised example of a custom tab bar I created for a project I am working on.
But in fact there is not so much to it, your tab bar component receives a navigation prop which holds the different routes you have set up in createMaterialTopTabNavigator
. So you simply loop over those routes and display an tab bar item for each of them.
CustomTabBar.jsx
export default class CustomTabBar extends React.Component {
render() {
const {navigation} = this.props;
const routes = navigation.state.routes;
return (
<SafeAreaView style={{backgroundColor: 'blue'}}>
<View style={styles.container}>
{routes.map((route, index) => {
return (
<View style={styles.tabBarItem}>
<CustomTabBarIcon
key={route.key}
routeName=route.routeName
onPress={() => this.navigationHandler(index)}
focused={navigation.state.index === index}
index={index}
/>
</View>
);
}
</View>
</SafeAreaView>
);
}
navigationHandler = (routeName) => {
this.props.navigation.navigate(routeName);
}
}
const styles = StyleSheet.create({
container: {
flexDirection: 'row',
alignContent: 'center',
height: 56,
width: '100%',
paddingHorizontal: 16,
backgroundColor: 'blue',
},
tabBarItem: {
flex: 1,
alignItems: 'center'
}
});
CustomTabBarItem.jsx
class CustomTabBarIcon extends React.PureComponent {
render() {
const {index, focused, routeName} = this.props;
let icon = '';
switch (index) {
case 0:
icon = 'a';
break;
case 1:
icon : 'b';
break;
case 2:
icon = 'c';
break;
default:
iconName = 'a';
}
return (
<TouchableWithoutFeedback
onPress={() => this.onSelect(routeName)}
>
<View style={[styles.container, focused ? styles.active : styles.inactive]}>
<View style={styles.icon}>
<Icon name={icon} color='white' size={24}/>
</View>
<Text style={styles.textStyle}>{routeName}</Text>
</View>
</TouchableWithoutFeedback>
);
}
onSelect = (routeName) => {
this.props.onPress(routeName);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
alignItems: 'center'
},
active: {
borderTopWidth: 3,
borderColor: 'white'
},
inactive: {
borderTopWidth: 3,
borderColor: 'blue'
},
textStyle: {
color: 'white',
fontSize: 13
}
});
A very simple approach will be to use Fragment from react. It solves the problem.
import React, {Fragment} from 'react';
And your component return could look like this
return (
<Fragment>
<MyCustomHeader/>
<MaterialTopTabBar/>
</Fragment>
)