问题
I am using createMaterialTopTabNavigator from react-navigation and trying to customize the tab bar by adding some components on top of it.
As you can see in its guide here:
https://reactnavigation.org/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 completely overrides the tab bar which is not what I want.
I'd like to add a custom component 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 component 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 components and tabs)
const myNavigation = createMaterialTopTabNavigator({
firstTab: FirstTabScreen,
secondTab: SecondTabScreen,
thirdTab: ThirdTabScreen,
},
{
tabBarComponent: props => (
<View><Text>My Custom Component</Text></View>
)
});
回答1:
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
}
});
回答2:
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>
)
回答3:
You can add your own custom component to the existing top tab bar like this:
import { createMaterialTopTabNavigator, MaterialTopTabBar } from "react-navigation";
tabBarComponent: props => <SafeAreaView>
<MyCustomHeader title='test' />
<MaterialTopTabBar {...props} />
</SafeAreaView>
来源:https://stackoverflow.com/questions/54409280/how-to-add-a-custom-component-to-creatematerialtoptabnavigator-tab-bar