Skip to content

Instantly share code, notes, and snippets.

@charlesxsh
Last active June 22, 2020 01:40
Show Gist options
  • Save charlesxsh/e2758e2810ccf48a92775617af01c5ff to your computer and use it in GitHub Desktop.
Save charlesxsh/e2758e2810ccf48a92775617af01c5ff to your computer and use it in GitHub Desktop.
Customize tab bar in react native using react navigation
import React from 'react';
import { Component } from 'react';
import {
TouchableOpacity,
Text,
View,
Image
} from 'react-native';
import { TabBarBottomProps, NavigationRoute } from 'react-navigation';
// just for ide hints
interface TabBarProps extends TabBarBottomProps {
}
interface TabBarState {
}
class TabBar extends Component<TabBarProps, TabBarState> {
navigationStateIndex = null;
// call when each time user click different tab
navigationAvaliableFuncs: {
[key: string]: () => boolean
} = {
//Account: this._needSignIn.bind(this),
//Progress: this._needSignIn.bind(this),
}
// call when clicking tab got refused
navigationRefusedFuncs: {
[key: string]: () => void
} = {
Account: this._refusedByNeedSignIn.bind(this),
Progress: this._refusedByNeedSignIn.bind(this)
}
constructor(props: TabBarProps) {
super(props);
}
/* _needSignIn() {
return !!this.props.authToken;
} */
/*_refusedByNeedSignIn() {
const { navigation } = this.props;
navigation.navigate('...');
}*/
// Main function to render tabbar
renderTabBarButton(route: NavigationRoute, idx: any) {
const {
activeTintColor,
inactiveTintColor,
navigation,
getLabelText,
renderIcon,
} = this.props;
const currentIndex = navigation.state.index;
const color = currentIndex === idx ? activeTintColor : inactiveTintColor;
const label = getLabelText({ route, focused: currentIndex === idx, index: idx });
return (
<TouchableOpacity
onPress={() => {
if (currentIndex != idx) {
if (this.isNavigateAvaliable(label as string)) {
navigation.navigate(route.routeName);
} else {
this._onNavigationRefused(label as string);
}
}
}}
style={StdStyles.tabBarButton}
key={route.routeName}
>
{renderIcon({ route, tintColor: color, focused: currentIndex === idx, index: idx })}
// uncomment if you need title under tab
{/* <Text style={[ StdStyles.tabBarButtonText, { color }]}>
{label}
</Text> */}
</TouchableOpacity>
);
}
isNavigateAvaliable(label: string) {
const func: any = this.navigationAvaliableFuncs[label];
if (func) {
return func();
}
return true;
}
_onNavigationRefused(label: string) {
const func = this.navigationRefusedFuncs[label];
if (func) {
func();
}
}
render() {
const { navigation, style } = this.props;
const tabBarButtons = navigation.state.routes.map(this.renderTabBarButton.bind(this));
return (
<View style={[StdStyles.tabBar, style]}>
{tabBarButtons}
</View>
);
}
}
// Possible extension with redux
// function mapStateToProps(state: any) {
// return {
// ....,
// }
// }
// function mapDispatchToProps(dispatch) {
// return bindActionCreators(..., dispatch);
// }
// const _TabBar = connect(mapStateToProps)(TabBar);
// export { _TabBar as TabBar };
@AsadSaleh
Copy link

Can anyone provide with a non-TypeScript code? Just JSX as we know it. That would be a huge help for me, personally. Thanks

@aaronbalthaser
Copy link

What version of react navigation are you using? As far as I can tell TabBarBottomProps & NavigationRoute cannot be resolved. Do you know why?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment