I am using createMaterialTopTabNavigator
from react-navigation
and trying to customize the tab bar by adding some ponents on top of it.
As you can see in its guide here:
.html#docsNav
there is an option called tabBarComponent
that can be passed to create your own tab bar. However, it pletely overrides the tab bar which is not what I want.
I'd like to add a custom ponent at the top of the tab bar and then have the default tabs with their labels underneath.
Can anyone show me an example of how to add a ponent to the tab bar please?
For example the code bellow replaces the tabs with My Custom Component
text but how can I have both of them? (custom ponents and tabs)
const myNavigation = createMaterialTopTabNavigator({
firstTab: FirstTabScreen,
secondTab: SecondTabScreen,
thirdTab: ThirdTabScreen,
},
{
tabBarComponent: props => (
<View><Text>My Custom Component</Text></View>
)
});
I am using createMaterialTopTabNavigator
from react-navigation
and trying to customize the tab bar by adding some ponents on top of it.
As you can see in its guide here:
https://reactnavigation/docs/en/material-top-tab-navigator.html#docsNav
there is an option called tabBarComponent
that can be passed to create your own tab bar. However, it pletely overrides the tab bar which is not what I want.
I'd like to add a custom ponent at the top of the tab bar and then have the default tabs with their labels underneath.
Can anyone show me an example of how to add a ponent to the tab bar please?
For example the code bellow replaces the tabs with My Custom Component
text but how can I have both of them? (custom ponents and tabs)
const myNavigation = createMaterialTopTabNavigator({
firstTab: FirstTabScreen,
secondTab: SecondTabScreen,
thirdTab: ThirdTabScreen,
},
{
tabBarComponent: props => (
<View><Text>My Custom Component</Text></View>
)
});
Share
Improve this question
edited Jan 28, 2019 at 20:25
HTB
asked Jan 28, 2019 at 19:50
HTBHTB
4231 gold badge9 silver badges22 bronze badges
3
- In this case you will need to create a custom tab bar ponent. But it is in fact a lot easier than it sounds, so no worries – dentemm Commented Jan 28, 2019 at 20:01
- @dentemm that's my problem! I've been trying to create a custom tab bar. And I can assign it to the tabBarComponent. but it removes the original tabs. Do you mind showing me an example please? I've been struggling with it in the past few days, but no luck – HTB Commented Jan 28, 2019 at 20:05
- 1 I will show an example of a tab bar I have created! – dentemm Commented Jan 28, 2019 at 20:22
3 Answers
Reset to default 7It is not so difficult to create a custom tab bar ponent, 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 ponent 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 ponent return could look like this
return (
<Fragment>
<MyCustomHeader/>
<MaterialTopTabBar/>
</Fragment>
)
You can add your own custom ponent to the existing top tab bar like this:
import { createMaterialTopTabNavigator, MaterialTopTabBar } from "react-navigation";
tabBarComponent: props => <SafeAreaView>
<MyCustomHeader title='test' />
<MaterialTopTabBar {...props} />
</SafeAreaView>