Adding Header button and title for BottomTabNavigator in Vue Native - react-native

I have created a bottom navigator like this:
const IOSTabs = createBottomTabNavigator(
{
Home: {
screen: HomeScreen,
navigationOptions: {
headerStyle: {backgroundColor: 'green'},
title: 'Home',
tabBarLabel: 'Homes',
tabBarIcon: <Icon name="home-outline" size={25}/>,
}
},
Settings: {
screen: SettingsScreen,
navigationOptions: {
tabBarIcon: <Icon name="settings-outline" size={25} />
}
}
}
);
const StackNavigator = createStackNavigator(
{
Home: IOSTabs
}
);
const AppNavigator = createAppContainer(StackNavigator);
export default {
components: { AppNavigator }
}
This works fine, and though the header is showing, the title is empty and cannot add buttons or text to it. I thought that the title should display the header but it doesn't.
What am I missing here?

Related

How to properly stack nested navigators within an App Container?

I currently have an AppContainer which consists of a bottom tab navigator and currently one more navigation set for Profile settings. I am trying to understand how to properly arrange everything, specifically how to nest navigation in one tab Profile so I can access two other pages QrCode and EditAccount each through two buttons. How do I achieve the below output? I believe I have to nest profile navigation somehow.
MY TABS BELOW
Home
Queue
Profile
:in here i have two other pages i can access QRCode and EditAccounts
App.js
const bottomTabNavigator = createBottomTabNavigator(
{
Home: {
screen: Home,
navigationOptions: {
tabBarIcon: ({ tintColor }) => (
<Icon name="home" size={25} color={tintColor} />
)
}
},
Queue: {
screen: Queue,
navigationOptions: {
tabBarIcon: ({ tintColor }) => (
<Icon name="comments" size={25} color={tintColor} />
)
}
},
Profile: {
screen: Profile,
navigationOptions: {
tabBarIcon: ({ tintColor }) => (
<Icon name="user" size={25} color={tintColor} />
)
}
}
})
const navigationOptions = ({ navigation }) => {
return {
headerTitle: 'hello',
headerStyle: {
height: '45%',
backgroundColor: 'black'
},
headerTintColor: 'white',
headerLeft: (
<TouchableWithoutFeedback
style={{ /* Put your style here */}}
onPress={() => navigation.goBack()} >
<Ionicons name="ios-arrow-dropleft" size={32} color="white" />
</TouchableWithoutFeedback>
)
}
}
const ProfileNavigator = createStackNavigator({
//Profile: { screen: Profile},
QR: { screen: GenerateQR, navigationOptions },
Profile: { screen: Profile },
EditAccount: { screen: EditAccount, navigationOptions }
});
const AppNavigator = createSwitchNavigator({
tabs: bottomTabNavigator,
profile: ProfileNavigator
})
const AppContainer = createAppContainer(AppNavigator);
After Applying Answer
The solution offers works as needed with the code below:
const navigationOptions = ({ navigation }) => {
return {
headerTitle: 'hello',
headerStyle: {
height: '45%',
backgroundColor: 'black'
},
headerTintColor: 'white',
headerLeft: (
<TouchableWithoutFeedback
style={{ /* Put your style here */}}
onPress={() => navigation.goBack()} >
<Ionicons name="ios-arrow-dropleft" size={32} color="white" />
</TouchableWithoutFeedback>
)
}
}
const ProfileNavigator = createStackNavigator({
Profile: { screen: Profile},
QR: { screen: GenerateQR, navigationOptions },
EditAccount: { screen: EditAccount, navigationOptions }
});
//ADDED
ProfileNavigator.navigationOptions = () => {
const navigationOptions = {
header: null,
headerMode: 'none',
};
return navigationOptions;
};
const AppNavigator = createSwitchNavigator({
tabs: bottomTabNavigator,
profile: ProfileNavigator
})
const AppContainer = createAppContainer(AppNavigator);
The only issue is I am unsure how to port over the header options to the tabs in the in the bottomTabNavigator. I have a custom component in place for the profile page that makes it look like this (black bar with button icon for Profile):
I can then navigate to the EditAccounts by pressing on the user icon. But when I navigate back from EditAccounts back to profile, the page renders with the navigationOptions header like so:
How do I apply this properly so I can lean simply on the navigationOptions header and push a custom name onto it (get rid of my custom component in that case)?
There are 2 cases.
If you want to keep tabs when accessing QR or EditAccount
const BottomTabNavigator = createBottomTabNavigator({
...
Profile: {
screen: ProfileNavigator,
}
})
const ProfileNavigator = createStackNavigator({
Profile: { screen: Profile},
QR: { screen: GenerateQR, navigationOptions },
EditAccount: { screen: EditAccount, navigationOptions }
});
ProfileNavigator.navigationOptions = () => {
const navigationOptions = {
header: null,
headerMode: 'none',
};
return navigationOptions;
};
const AppContainer = createAppContainer(BottomTabNavigator);
If you don't want to keep tabs
const BottomTabNavigator = createBottomTabNavigator({
...
Profile: {
screen: Profile,
}
})
const AppNavigator = createStackNavigator({
Tabs: BottomTabNavigator,
QR: { screen: GenerateQR, navigationOptions },
EditAccount: { screen: EditAccount, navigationOptions }
})
const AppContainer = createAppContainer(AppNavigator);
UPDATED:
Add navigationOptions to ProfileNavigator to remove header
ProfileNavigator.navigationOptions = () => {
const navigationOptions = {
header: null,
headerMode: 'none',
};
return navigationOptions;
};

How can a TabNavigator child screen refer to parent StackNavigator?

i am trying to navigate from child tab navigator to a screen of parent stack navigator. But this.props.navigation.navigate can only navigate to child's navigation props
'
//stack.js
const AppNavigator = createStackNavigator(
{
DetailPage: DetailPage, //Screen A
MainScreen: { . //Screen B
screen: MainScreen,
navigationOptions: {
header: null
}
}
{
initialRouteName: "MainScreen"
}
}
//MainScreen.js
<View style={{ flex: 1 }}>
<TabScreen />
</View>
//TabScreen.js
const TabScreen = createMaterialTopTabNavigator({
Home: {
screen: HomeStack
},
// Videos: { screen: Videos },
Videos: {
screen: Videos
},
Shows: {
screen: AllShows
},
Live: {
screen: Live
}
})'
I want to navigate from (TabNavigator)TabScreen's Home to (StackNavigator)AppNavigator's DetailPage. But OnPress does Nothing. However, it can navigate to different screens of TabNavigator(child navigator).
Please help me how can I navigate from child TabNavigator to Parent StackNavigator
Nope. you cant do something like this. You need to make sure there is only one navigator defined. If not, need to make sure the navigation state is connected so that navigators know each other. I would strongly suggest you use a single root navigation
Refer Common Mistakes in react navigation
Explicitly rendering more than one navigator
Most apps should only ever render one navigator inside of a React component, and this is usually somewhere near the root component of your app. This is a little bit counter-intuitive at first but it's important for the architecture of React Navigation.
You need to define everything in a single place (root). Like follows
import React, { Component } from "react";
import { View, Text } from "react-native";
import { createStackNavigator, createAppContainer } from "react-navigation";
import { createMaterialBottomTabNavigator } from "react-navigation-material-bottom-tabs";
import Camera from "./screens/camera";
import Welcome from "./screens/welcome";
import Scanner from "./screens/scanner";
import Cards from ".//screens/cards";
const BottomNavigation = createMaterialBottomTabNavigator(
{
Scan: { screen: Scanner },
Cards: { screen: Cards },
Settings: { screen: Cards }
},
{
initialRouteName: "Scan",
shifting: true
}
);
const AppNavigator = createStackNavigator({
Welcome: {
screen: Welcome,
navigationOptions: { header: null }
},
Camera: {
screen: Camera,
navigationOptions: { header: null }
},
Home: {
screen: BottomNavigation,
navigationOptions: { header: null }
}
});
export default createAppContainer(AppNavigator);
Now i believe you can navigate to different screens as everything is defined on a single navigator.
Could you try this?
//stack.js
const AppNavigator = createStackNavigator(
{
DetailPage: DetailPage, //Screen A
MainScreen: { . //Screen B
screen: MainScreen,
navigationOptions: {
header: null
}
},
TabScreen : {
screen : TabScreen
},
{
initialRouteName: "TabScreen"
}
}
//TabScreen.js
const TabScreen = createMaterialTopTabNavigator({
Home: {
screen: HomeStack
},
// Videos: { screen: Videos },
Videos: {
screen: Videos
},
Shows: {
screen: AllShows
},
Live: {
screen: Live
}
},
{
initialRouteName: "Home"
}
)'
this.props.navigation.dangerouslyGetParent().navigate('routeName', {});
Also, if you are ready to refactor some code you can create a new Screen and create some extra components, you can create a MainTabScreen for each TabNavigation screen, then:-
App.js
<NavigationContainer>
<Stack.Navigator
screenOptions={{
headerShown: false
}}
>
<Stack.Screen
name="login"
component={LogIn}
options={{title : 'LOG IN', headerShown: true}}
/>
<Stack.Screen
name="client-tabs-main"
component={ClientTabsMain}
/>
... Other Screens ...
</Stack.Navigator>
</NavigationContainer>
ClientsTabMain.jsx
<Tabs.Navigator
activeColor='white'
barStyle={{backgroundColor: colors.primary}}
>
<Tabs.Screen
name="home-tabs"
component={HomeTab}
options={{
tabBarLabel: 'Home',
tabBarIcon: ({ color }) => (
<MaterialCommunityIcons name="home-outline" color={color} size={18} />
),
}}
/>
<Tabs.Screen
name="portfolio-tabs"
component={PortfolioTab}
options={{
tabBarLabel: 'Portfolio',
tabBarIcon: ({ color }) => (
<MaterialCommunityIcons name="clock" color={color} size={18} />
)
}}
/>
... Other Screens ...
</Tabs.Navigator>
PortfolioTabs.jsx
<PortfolioStack.Navigator
screenOptions={{
headerShown: true
}}
>
<PortfolioStack.Screen
name="portfolio"
component={Portfolio}
options={{
title: 'Portfolio'
}}
/>
<PortfolioStack.Screen
name="transaction"
component={Transaction}
/>
</PortfolioStack.Navigator>
And navigate using :-
this.props.navigation.replace('client-tabs-main',{
screen: 'portfolio-tabs',
params: {
screen: 'portfolio'
}
});
createBottomTabNavigator({
HomeTab: {
screen: HomeStack,
navigationOptions: {
title: "Home",
tabBarOnPress: this.handleTabPress
}
},
MessagingTab: {
screen: MessagingStack,
navigationOptions: {
title: "Messaging",
tabBarOnPress: this.handleTabPress
}
}
});
handleTabPress = ({ navigation }) => {
navigation.popToTop();
navigation.navigate(navigation.state.routeName);
}`

How to hide navigation header after adding in nested screens react-native

I have Main screen in which there is a headerbar also this screen contain 2 tabs name Home and Settings , these two tabs have their own header bar their is a button inside my Home Screen which when click calls Details Screen from this Detail Screen i want to hide Main Screen header bar
Code for MainScreen HeaderBar
const TabScreen = createStackNavigator({
TabScreen: {
screen: RootStack,
navigationOptions: {
headerTitle: 'Tabs'
},
},
});
Code For Tabs
const RootStack = createMaterialTopTabNavigator(
{
Home: {
screen: HomeRoot,
navigationOptions : {
tabBarLabel: 'Home',
tabBarIcon: <Image source={{uri:
'https://png.icons8.com/Home/ultraviolet/50/3498db'}} style={{width:20,
height: 20}}/>
},
},
Settings: {
screen: Settings,
navigationOptions : {
tabBarLabel: 'Setting',
tabBarIcon: <Image source={{uri:
'https://png.icons8.com/Home/ultraviolet/50/3498db'}} style= .
{{width:20, height: 20}}/>
},
},
},
Code for Home and Details Screen
const HomeRoot = createStackNavigator(
{
Home: {
screen: Home,
},
Details: {
screen: Details,
},
},
{
initialRouteName: 'Home',
}
);
Is this what you are looking for?
headerMode: 'none',

How to force drawer to be over header with react navigation

I saw other answers regarding this issue but I can't find solution.
I want to show drawer always above app screen and above header. Instead drawer is always bellow header.
What am I doing wrong here:
const AppNavigation = createStackNavigator(
{
Main: { screen: Main, navigationOptions: {
title: "Main"
} },
Home: { screen: Home, navigationOptions: {
title: "Home"
} }
},
{
initialRouteName: "Main"
}
);
const DrawerNavigation = createDrawerNavigator(
{
Home: Home,
Main: Main
},
{
initialRouteName: "Main"
}
);
App = createStackNavigator({
drawer: {
screen: DrawerNavigation,
},
app: {
screen: AppNavigation
}
}, {
initialRouteName: 'drawer',
navigationOptions: ({navigation}) => ({
headerStyle: {backgroundColor: '#a9a9a9'},
title: 'Welcome!',
headerTintColor: 'white',
headerLeft: <Text onPress={() =>
navigation.dispatch(DrawerActions.toggleDrawer())}>Menu</Text>
})
});
export default () => (
<View style={{ flex: 1 }}>
<App />
</View>
Our app is similar to this. You can make the drawer be over the header with react-navigation if it is the <Root /> component of your app (the one you import into index.js). For example:
export const Root = DrawerNavigator({
Tabs: {
screen: Tabs,
title: 'Tabs'
},
STACK1: {
screen: STACK1,
title: 'STACK1',
},
STACK2: {
screen: STACK2,
title: 'STACK2',
},
});
That will give you something like this:

How to navigate to a screen from another screen inscribed in a 3 level navigator

I am a newbie to react native. I am using Login and Home screens in a stack navigator in which home screen consist a tab navigator with each tab having 2 or 3 screens; so i added a stack navigator inside that tab navigator (3 Level navigator).
app.js
export const SimpleApp = StackNavigator({
login: { screen: LoginPage },
homepage: { screen : HomePage },
});
home.js
export const MyApp = TabNavigator({
Asset: {
screen: AssetScreen,
navigationOptions: {
tabBarLabel: 'Asset',
tabBarIcon: (
<Image source={require('../logos/tab_assets.png')}
style={[styles.icon, {color: '#ffffff'}]}
/>
)
},
},
Sensors: {
screen: sensorsStack,
navigationOptions: {
tabBarLabel: 'Sensor',
tabBarIcon: (
<Image source={require('../logos/tab_sensor.png')}
style={[styles.icon, {color: '#ffffff'}]}
/>
)
},
},
Settings: {
screen: settingStack,
navigationOptions: {
tabBarLabel: 'Settings',
tabBarIcon: (
<Image source={require('../logos/tab_settings.png')}
style={[styles.icon, {color: '#ffffff'}]}
/>
)
},
},
}
With again stack navigator for sensors and settings tab.
export const sensorsStack = StackNavigator({
sensors : { screen: SensorScreen },
sensorDetails : { screen: SensorDetails }
});
export const settingStack = StackNavigator({
settings: { screen: SettingsScreen },
about : { screen: About },
environment : { screen: Environment }
});
I have signout button in settingsScreen, by clicking on it i want to navigate the screen to login which is in app.js stack.
I have tried using nagivation.back() in settingsScreen but it is going back to homepage not login. Is there any way i can achieve this? or any other way to provide login access to my app.