I am creating a sample hotels listing application with following menus:
export const loggedInMenu = createMaterialBottomTabNavigator(
{
Hotels: {
screen: hotelDetailsScreen,
navigationOptions: {
tabBarLabel: "Hotels",
tabBarIcon: <Icon name="hotel" size={24} />
}
},
HotelsSearch: {
screen: HotelsSearch,
navigationOptions: {
tabBarLabel: "Search",
tabBarIcon: <Icon name="search" size={24} />
}
},
Favourites: {
screen: Favourites,
navigationOptions: {
tabBarLabel: "Hotels",
tabBarIcon: <Icon name="favorite" size={24} />
}
},
},
{
initialRouteName: 'Hotels'
}
);
export const hotelDetailsScreen = createStackNavigator(
{
Hotels: {screen: Hotels},
hotelDetails: {screen: hotelDetails},
},
{
initialRouteName: "Hotels",
headerLayoutPreset: "center",
navigationOptions: {
title: "Hotels",
headerTransparent: true,
headerStyle: {
backgroundColor: '#694fad'
}
}
}
);
The code works, however with one exception that the initial hotels screen header is overlapping the view data. Any help appreciated.
Check the below output:
Turns out that the docs was misleading (at least for me). I specified headerTransparent: true, which was Not needed as I just wanted to set the background color on the screen. I removed it and started working well.
Related
How can I create a submenu in createStackNavigator?
I created my navigation as below:
const MainStackNavigator = createStackNavigator({
Home: {
screen: HomeScreen,
navigationOptions: {
headerTitle: 'iRent'
}
},
Company: {
screen: CompanyDetails,
navigationOptions: {
headerTitle: 'Company Details'
}
},
Snapshots: {
screen: PropSnapshot,
navigationOptions: {
headerTitle: 'Property Snapshots'
}
}
}, {
defaultNavigationOptions: ({ navigation }) => {
return {
headerLeft: (
<Ionicons
style={{ paddingLeft: 10 }}
onPress={() => navigation.openDrawer()}
name="md-menu"
size={30}
/>
)
};
}
});
const AppDrawerNavigator = createDrawerNavigator({
myApp: {
screen: MainStackNavigator
},
Home: {
screen: HomeScreen,
navigationOptions: {
drawerIcon: <FontAwesome name="home" size={20} />
}
},
Company: {
screen: CompanyDetails,
navigationOptions: {
drawerIcon: <FontAwesome name="building-o" size={20} />
}
},
Snapshots: {
screen: PropSnapshot,
navigationOptions: {
drawerIcon: <MaterialIcons name="data-usage" size={20} />
}
},
LogOut: {
screen: Login,
navigationOptions: {
title: 'Log Out',
drawerIcon: <Entypo name="log-out" size={20} />
}
}
});
const AppSwitchNavigator = createSwitchNavigator({
Login: { screen: Login },
ForgotPassword: { screen: ForgotPassword },
Main: { screen: AppDrawerNavigator }
});
const AppContainer = createAppContainer(AppSwitchNavigator);
It is working perfect, but how can I add submenus to the Company menu. I would like to have "Company Details", "Company Test" under the Company menu in the left menu bar. Is it possible to do using the createStackNavigator?
Thanks!
As far I understand, you need a dropdown menu which will contain your companies details when you click on company.
If you want this, then try to do with drawer navigation.
When you click on company a drawer will open between company and snapshot.
Rest navigate as you want.
I need to use state on my App.js code but react-navigation v3 don't use class so I can't define the constructor method.
Is there any other way so I can use state?
I tried to use a boolean javascript variable but it didn't help.
I use StackNavigator, drawer navigator and DrawerNavigator and BottomTabNavigator like this
const TabAppNavigator = createBottomTabNavigator({
Posts: {
screen: PostsScreen,
navigationOptions: {
tabBarLabel: 'Posts',
tabBarIcon: ({ tintColor }) => (<Icon name="md-home" color={tintColor} size={25} />)
}
},
Tools: {
screen: ToolsScreen,
navigationOptions: {
tabBarLabel: 'Tools',
tabBarIcon: ({ tintColor }) => (<Icon name="md-apps" color={tintColor} size={25} />)
}
},
Favourite: {
screen: FavouriteScreen,
navigationOptions: {
tabBarLabel: 'Favourite',
tabBarIcon: ({ tintColor }) => (<Icon name="md-heart" color={tintColor} size={25} />)
}
},
}, {
initialRouteName: 'Posts',
order: ['Posts', 'Tools', 'Favourite'],
tabBarOptions: {
activeTintColor: '#d94854',
inactiveTintColor: '#818181',
style: {
backgroundColor: '#fff',
borderTopColor: '#818181',
borderTopWidth: 1,
paddingBottom: 5,
paddingTop: 15,
},
labelStyle: {
fontSize: 13,
marginTop: 10,
},
},
navigationOptions: ({ navigation }) => {
return {
headerTitle: 'Growth Hack Toolkit',
headerTintColor: '#fff',
headerStyle: {
backgroundColor: '#d94854',
},
headerLeft: (
<Icon name="md-menu" color="#fff" size={25} style={{ paddingLeft: 15 }} onPress={() => navigation.openDrawer()} />
),
headerRight: (
<Icon name="md-search" color="#fff" size={25} style={{ paddingRight: 15 }} onPress={() => search()} />
)
}
}
}
)
const PostsStackAppNavigator = createStackNavigator({
TabAppNavigator: TabAppNavigator,
Posts: { screen: PostsScreen },
Post: { screen: PostScreen }
})
const ToolsStackAppNavigator = createStackNavigator({
TabAppNavigator: TabAppNavigator,
Tools: { screen: ToolsScreen },
Tool: { screen: ToolScreen },
ToolList: { screen: ToolListScreen },
Web: { screen: WebScreen },
Mobile: { screen: MobileScreen },
})
const DrawerAppNavigator = createDrawerNavigator({
Posts: { screen: PostsStackAppNavigator },
Tools: { screen: ToolsStackAppNavigator },
About: { screen: AboutScreen },
}, {
contentComponent: SideMenu,
drawerWidth: 250,
})
const App = createAppContainer(DrawerAppNavigator);
export default App;
I want to change my header view based on my state
basically, I have a default header (the same header for all tab screens) that contains a title, menu icon to open the drawer navigation and search icon to start searching
what I need to do is that when search icon is pressed I will change my state to show the instead of the title and when close icon is pressed I will change the state to show my default header again.
after spending so much time searching for a solution or a workaround, the answer is: I cannot.
It is not possible to have state in a functional component. So I have to use react navigation v2 instead of v3 as it is implemented as class-based component.
These links could help to understand:
difference between functional and class-based React components
React State without Constructor
import { createBottomTabNavigator } from 'react-navigation';
I am importing two files
import Profile from './app/profile'
import Home from './app/result'
Creating a bottom tab navigation which works but i just need to show custom icons where i can actually provide the icon path.
export default createBottomTabNavigator
({
Home: { screen: Home },
Profile: { screen: Profile }
},
{
initialRouteName: 'Discovery',
});
Is there any way to do that?
You can try using this one. This is a snippet of my code.
ShoutOut: {
screen:ShoutOut,
navigationOptions: {
tabBarLabel: 'ShoutOut',
tabBarIcon: ({tintColor, activeTintColor}) => (
<Icon name="ios-megaphone" size={30} color={tintColor} />
)
},
},
For your one should be...
export default createBottomTabNavigator
({
Home: {
screen: Home,
navigationOptions: {
tabBarLabel: 'Home',
tabBarIcon: ({tintColor, activeTintColor}) => (
<Icon name="home" size={30} color={tintColor} />
)
},
},
Profile: {
screen: Profile,
navigationOptions: {
tabBarLabel: 'Profile',
tabBarIcon: ({tintColor, activeTintColor}) => (
<Icon name="user" size={30} color={tintColor} />
)
},
}
},
{
initialRouteName: 'Discovery',
tabBarOptions: {
activeTintColor: '#fb9800',
inactiveTintColor: '#7e7b7b',
showIcon: true,
style: { height: 54,backgroundColor: '#fff',borderTopWidth:0.5,borderTopColor: '#fb9800' },
showLabel: true,
labelStyle: {
fontSize: 10,
}
}
});
I'm coding an app that uses react-navigation. My app has a bottom TabNavigator in which each tab consists of a stackNavigator, like so:
Routes.js:
const FirstStack = createStackNavigator({
First: {
screen: FirstScreen,
navigationOptions: {
header: props => <AppToolbar />
}
}
});
const SecondStack = createStackNavigator({
Second: {
screen: SecondScreen,
navigationOptions: {
header: props => <AppToolbar />
}
}
});
const ThirdStack = createStackNavigator({
Third: {
screen: ThirdScreen,
navigationOptions: {
header: props => <AppToolbar />
}
}
});
const FourthStack = createStackNavigator({
Fourth: {
screen: FourthScreen,
navigationOptions: {
header: props => <AppToolbar />
}
}
});
const FifthStack = createStackNavigator({
Fifth: {
screen: FifthScreen,
navigationOptions: {
header: props => <AppToolbar />
}
}
});
export const AppStack = createBottomTabNavigator(
{
First: {
screen: FirstStack,
navigationOptions: {
title: "First",
tabBarLabel: "First",
tabBarIcon: ({ tintColor }) => (
<Icon name="ios-home" color={tintColor} size={24} />
)
}
},
Second: {
screen: SecondStack,
navigationOptions: {
title: "Second",
tabBarLabel: "Second",
tabBarIcon: ({ tintColor }) => (
<Icon name="ios-clock" color={tintColor} size={24} />
)
}
},
Third: {
screen: ThirdStack,
navigationOptions: {
title: "Third",
tabBarLabel: "Third",
tabBarIcon: ({ tintColor }) => (
<Icon name="ios-fitness" color={tintColor} size={24} />
)
}
},
Fourth: {
screen: FourthStack,
navigationOptions: {
title: "Fourth",
tabBarLabel: "Fourth",
tabBarIcon: ({ tintColor }) => (
<Icon
name="ios-cloud-download"
color={tintColor}
size={24}
/>
)
}
},
Fifth: {
screen: FifthStack,
navigationOptions: {
title: "Fifth",
tabBarLabel: "Fifth",
tabBarIcon: ({ tintColor }) => (
<Icon name="ios-person" color={tintColor} size={24} />
)
}
}
},
{
initialRouteName: "First",
order: ["First", "Second", "Third", "Fourth", "Fifth"],
tabBarOptions: {
activeTintColor: "white",
inactiveTintColor: "grey",
style: {
backgroundColor: "#121212",
borderTopColor: "#303030"
}
}
}
);
Each stackNavigator inside the tabs in the tabNavigator has its own header so that I can customize the header for each tab, but all headers have a button which should navigate to the profile screen (in this example its the contact icon).
AppToolbar.js:
const appToolbar = props => {
return (
<View style={styles.toolbar}>
<Text style={styles.toolbarTitle}>Title</Text>
<TouchableOpacity onPress={...}>
<Icon
name="ios-contact"
color="grey"
size={30}
style={{ padding: 0, margin: 0, marginRight: 10 }}
/>
</TouchableOpacity>
</View>
);
};
What I want to do is that by pressing the contact icon the app should navigate to the profile screen, what I don't know is if its possible to define like a global route thats accesible from everywhere, Or do I have to add the profile screen to all the stackNavigators so that it is accesible from every screen in every stack?
Thanks in advance!
Found the answer here https://stackoverflow.com/a/50701940/1276438
Use a stackNavigator with the profile stack and the tabNavigator as children, making the tabNavigator the default route.
I have searched quite a bit in SO and haven't found a working solution to my problem,
Problem Statement : I have BottomTabNavigator with 5 tabs. Everytime i switch the tab i need to make an api call to fetch latest information. And to fetch latest information i need to have the redux store values that i need to use to make the api call. So how do i make those redux store values available in the function call that i make on tabChange?
Below is my function which needs to be called followed by the BottomTabNavigator,
fetchProfile = () => {
const {selectedPerson, dispatch, actions} = this.props
let Id = selectedPerson.Id
let personId = selectedPerson.placeId
dispatch(actions.getPersonDetails(Id, personId))
}
export const Tabs = createBottomTabNavigator({
Profile: {
screen: ProfileConnector,
navigationOptions: {
tabBarLabel: 'Profile',
tabBarIcon: ({tintColor}) => <Icon name="user" size={px2dp(22)} color={tintColor} onPress={() => fetchProfile()}/>,
},
// navigationOptions: ({ navigation }) => ({
// tabBarOnPress: (tab, jumpToIndex) => {
// console.log('onPress:', tab.route);
// jumpToIndex(tab.index);
// },
// tabBarLabel: 'Profile',
// tabBarIcon: ({tintColor}) => <Icon name="user" size={px2dp(22)} color={tintColor}/>,
// }),
},
Inbox: {
screen: InboxConnector,
navigationOptions: {
tabBarLabel: 'Inbox',
tabBarIcon: ({tintColor}) => <Icon name="inbox" size={px2dp(22)} color={tintColor}/>,
},
},
Bling: {
screen: BlingConnector,
navigationOptions: {
tabBarLabel: 'Bling',
tabBarIcon: ({tintColor}) => <Icon name="hand" size={px2dp(22)} color={tintColor}/>,
},
},
Calendar: {
screen: CalendarConnector,
navigationOptions: {
tabBarLabel: 'Calendar',
tabBarIcon: ({tintColor}) => <Icon name="calendar" size={px2dp(22)} color={tintColor}/>,
},
},
Misc: {
screen: Misc,
navigationOptions: {
tabBarLabel: 'Misc',
tabBarIcon: ({tintColor}) => <Icon name="bar-graph" size={px2dp(22)} color={tintColor}/>,
},
},
}, {
initialRouteName: 'Inbox',
tabBarPosition: 'bottom',
swipeEnabled: true,
scrollEnabled: true,
tabBarOptions: {
activeTintColor: 'teal',
inactiveTintColor: '#424949',
activeBackgroundColor: "white",
inactiveTintColor: '#424949',
labelStyle: { fontSize: 14 },
style : { height : 50},
}
});
Any help is much appreciated, i'm loosing my mind over this.
I have tried the commented out section above and with that it throws jumpToIndex is not a function
and the other option doesn't have the redux store values.
Please help. :(
Thanks,
Vikram
"Everytime i switch the tab i need to make an api call to fetch latest information."
You can detect willFocus/didFocus event of react-navigation and then fetch api
react-navigation: Detect when screen is activated / appear / focus / blur