Skip to content

Instantly share code, notes, and snippets.

@jsdario
Created November 14, 2016 23:45
Show Gist options
  • Save jsdario/2c914e972bd5075788ccc92c60966f29 to your computer and use it in GitHub Desktop.
Save jsdario/2c914e972bd5075788ccc92c60966f29 to your computer and use it in GitHub Desktop.
ex-navigation with custom navbar on andorid, plus navbar actions unified on both platforms
//set up the custom navbar for Android only
import CustomHeader from '...'
@observer
export default class App extends React.Component {
render() {
const navbarConfig = Platform.OS === 'android' ? {headerComponent: CustomHeader} : {}
return (
<StackNavigation
defaultRouteConfig={{
navigationBar: {
backgroundColor: '#049cdb',
tintColor: 'white',
},
}}
{...navbarConfig}
initialRoute={Router.getRoute(this.props.initialScreenString)}
/>
);
}
}
// These are some stores injected as props with the MobX Provider (through context).
// Redux has the same functionality too
// the useful side effect is that you can use these stores in the Screen.js in the onPress functions
// without explicitly passing them from the screen from which you're navigating
@inject("userStore", "jobStore", "projectStore")
@withNavigation
@observer
export default class CustomHeader extends PureComponent {
render() {
// safeJsonStringify(this.props)
if (!this.props.visible)return null
const {navigationState: {index, routes}} = this.props
const routeConfig = this.props.scene.route.config
const actions = routeConfig.navigationBar || {}
const route = this.props.scene.route
const self = this
let onRightBtnTap = (index: number) => {
actions.rightActions[index].onPress(route, self.props)
}
let leftButtonProps = {}
if (actions.leftAction) {
leftButtonProps.navIconName = actions.leftAction.iconName
leftButtonProps.onIconClicked = ()=>actions.leftAction.onPress(route, self.props)
} else if(this.props.scene.index > 0){
leftButtonProps.navIconName = 'arrow-back'
leftButtonProps.onIconClicked = ()=>this.props.navigator.pop()
}
let rightActions = (actions.rightActions && actions.rightActions.map((src)=> {
let action = {}
Object.assign(action, src)
action.iconName = (src.iconName && src.iconName.android)
return action
}
)) || []
let title = (routeConfig.navigationBar && routeConfig.navigationBar.title) || ''
let center = null
if (routeConfig.navigationBar && typeof routeConfig.navigationBar.title === 'function') {
title = routeConfig.navigationBar.title(route.params, self.props);
}
if (routeConfig.navigationBar && typeof routeConfig.navigationBar.renderTitle === 'function') {
center = routeConfig.navigationBar.renderTitle(route, self.props);
}
// const center = actions.center && actions.center(routes[index], self.props) || null
return <Icon.ToolbarAndroid
actions={rightActions}
onActionSelected={onRightBtnTap}
titleColor="white"
subtitleColor="white"
style={[globalStyles.header, StyleSheet.absoluteFill]}
overflowIconName="more-vert"
title={title}
{...leftButtonProps}
>
{center}
</Icon.ToolbarAndroid>
}
}
The code assumes modifications to ex-navigation: https://github.com/vonovak/ex-navigation/commit/c862c22a0023754cac24b6f61e61c2cf4aee5f75
The ExNavigationButtons.js is wip, it currently directly uses `react-native-vector-icons`
const right = [
{
//todo remove the keys in `iconName`
title: 'Search', iconName: {android: 'search', ios: 'ios-search'}, show: 'always', onPress: ({params}, props)=> {
let searchHelper = new SearchHelper(props.projectStore)
props.navigator.push(Router.getRoute('SearchScreen', {searchHelper}))
}
},
{
title: 'Filter', iconName: {android: 'filter-list'}, show: 'always', onPress: (route, props)=> {
props.navigation.getNavigator('master').push(Router.getRoute('FilterProjectScreen'))
}
},
{
title: 'User accounts', iconName: {android: 'people'}, show: 'never', onPress: (route, props)=> {
props.navigator.push(Router.getRoute('UserAccountsScreen'))
}
},
// {title: 'Settings', show: 'never'},
]
// the navbar config of this screen
static route = {
navigationBar: {
title: 'Projects',
leftAction: Platform.OS === 'ios' &&
{
title: 'new', iconName: {ios: 'ios-add'}, onPress: (route, props)=> {
props.navigation.getNavigator('master').push(Router.getRoute('AddProjectScreen'))
}
},
rightActions: Platform.OS === 'ios' ? [right[0]] : right
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment