A screen of my app (FeedScreen) has a top-right header button. I want that button to navigate to another screen on press.
This is my code:
const Stack = createNativeStackNavigator();
function App({ navigation }) {
return (
<>
<StatusBar hidden />
<NavigationContainer>
<Stack.Navigator initialRouteName="Home">
<Stack.Screen name="Home" component={HomeScreen} />
<Stack.Screen name="Login" component={LoginScreen} />
<Stack.Screen name="Signup" component={SignupScreen} />
<Stack.Screen name="TestScreen" component={TestScreen} />
<Stack.Screen name="CarouselScreen" component={CarouselScreen} />
<Stack.Screen name="SettingsScreen" component={SettingsScreen} />
<Stack.Screen name="InsertNumberScreen" component={InsertNumberScreen} />
<Stack.Screen name="FeedScreen"
component={FeedScreen}
options={{
title: 'My screen',
headerStyle: {
backgroundColor: '#262423',
},
headerTintColor: '#fff',
headerTitleStyle: {
fontWeight: 'bold',
},
headerRight: () => (
<Button
onPress={() => navigation.navigate('UploadPictureScreen')}
title="+"
color="#fff"
/>
),
}}
/>
<Stack.Screen name="UploadPictureScreen"
component={UploadPictureScreen}
options={{
title: 'Upload a picture',
headerStyle: {
backgroundColor: '#262423',
},
headerTintColor: '#fff',
headerTitleStyle: {
fontWeight: 'bold',
},
}}
/>
</Stack.Navigator>
</NavigationContainer>
</>
);
}
Unfortunately, it returns "Undefined is not an object (evaluating 'navigation.navigate')".
You can pass a function to options which receives an object with route and navigation properties.
<Stack.Screen
name="FeedScreen"
component={FeedScreen}
options={({ route, navigation }) => ({
title: "My screen",
headerStyle: {
backgroundColor: "#262423"
},
headerTintColor: "#fff",
headerTitleStyle: {
fontWeight: "bold"
},
headerRight: () => (
<Button
onPress={() => navigation.navigate("UploadPictureScreen")}
title="+"
color="#fff"
/>
)
})}
/>
Related
I have a MainPage component, and in the MainPage component, there are PostList, Post, and Explain components as Stack.Screen. and i made Home component
this is my code
const home = () => {
return (
<View>
<Text>home</Text>
</View>
)
}
const MainPage = () => {
return (
<Stack.Navigator>
<Stack.Screen
name="PostList"
component={PostList}
options={{headerShown: false}}
/>
<Stack.Screen
name="Post"
component={Post}
options={{headerShown: false}}
/>
<Stack.Screen
name="Explain"
component={Explain}
options={{
headerShown: false,
}}
/>
</Stack.Navigator>
);
};
And MainPage is wrapped with Tab.screen.
<Tab.Navigator>
<Tab.Screen
name="MainPage"
component={MainPage}
options={{
headerShown: false,
tabBarStyle: {display: 'none'},
tabBarIcon: ({color}) => (
<FontAwesome5 name="list" size={20} style={{color}} />
),
tabBarActiveTintColor: 'blue',
}}
/>
</Tab.Navigator>
I want to navigate to Home component using drawer navigation in MainPage component inside Tab.Screen.
so i tried like this code
<Drawer.Navigator initialRouteName="Home">
<Tab.Navigator>
<Tab.Screen
name="MainPage"
component={MainPage}
options={{
headerShown: false,
}}
/>
</Tab.Navigator>
</Drawer.Navigator>
but it doesn't work. How can i fix my code?
<NavigationContainer>
<Stack.Navigator screenOptions={{}}>
<Stack.Screen name="home" component={Home} />
<Stack.Screen
name="MyProfile"
component={Profile}
options={{
headerTintColor: 'white',
title: 'My Profile',
headerTransparent: true,
headerShadowVisible: false,
headerRight: () => (
<TouchableOpacity>
<DrawerIcon size={30} color={'white'} name="md-reorder-two-sharp" />
</TouchableOpacity>
),
headerLeft: () => (
<TouchableOpacity>
<Ionicons
name="arrow-back-sharp"
size={22}
color="white"
style={{ marginRight: 7, marginTop: 1, marginLeft: 3 }}
/>
</TouchableOpacity>
),
}}
/>
</Stack.Navigator>
<ModalPortal />
</NavigationContainer>
Below is the code I used for my stack navigation, and I want to go back from that screen
1.headerLeft: () => <TouchableOpacity>
<Ionicons name="arrow-back-sharp" size={22} color="white" style={{ marginRight: 7, marginTop: 1, marginLeft: 3 }} />
</TouchableOpacity>
}} />
There are two ways you can achieve this
1.) Set options On the Screen itself
You can use the useLayoutEffect hook to achieve this
On the screen where you want to put this header, i.e., the Profile screen just add the following code
React.useLayoutEffect(() => {
navigation.setOptions({
headerLeft: () => (
<Ionicons
name="arrow-back-sharp"
size={22}
color="white"
style={{ marginRight: 7, marginTop: 1, marginLeft: 3 }}
onPress={() => navigation.goBack()}
// make sure you destructure the navigation variable from the props
// or otherwise you'll have to write it like this
// onPress={() => props.navigation.goBack()}
/>
),
});
}, [navigation]);
And your Navigation Container should look like
<NavigationContainer>
<Stack.Navigator screenOptions={{}}>
<Stack.Screen name="home" component={Home} />
<Stack.Screen
name="MyProfile"
component={Profile}
options={{
headerTintColor: 'white',
title: 'My Profile',
headerTransparent: true,
headerShadowVisible: false,
}}
/>
</Stack.Navigator>
<ModalPortal />
</NavigationContainer>;
Have a look at the Working Example Here
2.) Set the headerLeft and headerRight props in the Navigation Container
Setting the properties in the NavigationContainer, like this
<NavigationContainer>
<Stack.Navigator screenOptions={{}}>
<Stack.Screen name="home" component={Home} />
<Stack.Screen
name="MyProfile"
component={Profile}
options={({ navigation, route }) => ({
headerTintColor: 'white',
title: 'My Profile',
headerTransparent: true,
headerShadowVisible: false,
headerRight: () => (
<TouchableOpacity>
<DrawerIcon size={30} color={'white'} name="md-reorder-two-sharp" />
</TouchableOpacity>
),
headerLeft: () => (
<TouchableOpacity onPress={() => navigation.goBack()}>
<Ionicons
name="arrow-back-sharp"
size={22}
color="white"
style={{ marginRight: 7, marginTop: 1, marginLeft: 3 }}
/>
</TouchableOpacity>
),
})}
/>
</Stack.Navigator>
<ModalPortal />
</NavigationContainer>
Have a look at the Working Example Here
You have provided a TouchableOpacity as the back button but you haven't specified any onPress callback. You should provide an onPress callback to your TouchableOpacity.
<NavigationContainer>
<Stack.Navigator screenOptions={{}}>
<Stack.Screen name='home' component={Home} />
<Stack.Screen
name='MyProfile'
component={Profile}
options={({ navigation, route }) => ({
headerTintColor: 'white',
title: 'My Profile',
headerTransparent: true,
headerShadowVisible: false,
headerRight: () => (
<TouchableOpacity>
<DrawerIcon size={30} color={'white'} name='md-reorder-two-sharp' />
</TouchableOpacity>
),
headerLeft: () => (
<TouchableOpacity onPress={()=> navigation.goBack()}>
<Ionicons name="arrow-back-sharp" size={22} color="white" style={{ marginRight: 7, marginTop: 1, marginLeft: 3 }} />
</TouchableOpacity>
)
})}
/>
</Stack.Navigator>
<ModalPortal />
</NavigationContainer>
If you just wanted to change the back button appearance only, You are better off with headerBackImage props of react-navigation stack.
Here's a Live Snack Example
I found some answers with old versions of navigation, with "tabBarVisible" option in Tab Navigator.
But since there is no more this option I want to know how to hide Tab Bar in specific screens INSIDE Stack Navigators
This is my Tab Navigator:
<Tab.Navigator
initialRouteName='Passports'
screenOptions={{
"tabBarLabelStyle": {
"fontSize": 12
},
"tabBarStyle": {
"backgroundColor": "white"
}
}}
>
<Tab.Screen
name='EquipmentStack'
component={EquipmentStack}
options={{
tabBarLabel:'Equipment'
}}
/>
<Tab.Screen
name='ObjectsStack'
component={ObjectsStack}
options={{ tabBarLabel:'Objects'}}
/>
<Tab.Screen
name='DocumentationStack'
component={DocumentationStack}
options={{ tabBarLabel:'Documentation'}}
/>
</Tab.Navigator>
And my First Stack navigator:
<Stack.Screen
name='Equipment'
component={Equipment}
options={{headerShown: false}}
/>
<Stack.Screen
name='Equipment Details'
component={EquipmentDetails}
options={{title:'Equipment Details'}}/>
<Stack.Screen
name='Equipment Details Update'
component={EquipmentDetailsUpdate}
options={{title:'Equipment Details Update'}}/>
<Stack.Screen
name='Equipment Details Update Zander'
component={EquipmentDetailsUpdateZander}
options={{title:'Equipment Details Update Zander'}}/>
</Stack.Navigator>
I want to hide Tab Bar only in 3 screens out of 4 in my stack:
"Equipment" 1 Screen : Tab Bar
"Equipment Details" 2 Screen : No Tab Bar
"Equipment Details Update" 3 Screen : No Tab Bar
"Equipment Details Update Zander" 4 Screen : No Tab Bar
Also My 2 other Stack Navigator are same, and i also want to do same thing to them :
<Stack.Navigator>
<Stack.Screen
name='Objects'
component={Objects}
options={{headerShown: false}}/>
<Stack.Screen
name='Objects Details'
component={ObjectsDetails}/>
<Stack.Screen
name='Objects Details Update'
component={ObjectsDetailsUpdate}/>
</Stack.Navigator>
<Stack.Navigator>
<Stack.Screen
name='Documentation'
component={Documentation}
options={{headerShown: false}}/>
<Stack.Screen
name='Documentation Details'
component={DocumentationDetails}/>
<Stack.Screen
name='Documentation Details Update'
component={DocumentationDetailsUpdate}/>
</Stack.Navigator>
As per my understanding what you are trying to achieve can be done as below. can you check
export const TabNavigation = () => {
return (
<Tab.Navigator
initialRouteName="Passports"
screenOptions={{
tabBarLabelStyle: {
fontSize: 12,
},
tabBarStyle: {
backgroundColor: 'white',
},
}}>
<Tab.Screen
name="Equipment"
component={Equipment}
options={{
tabBarLabel: 'Equipment',
headerShown: false,
}}
/>
<Tab.Screen
name="Objects"
component={Objects}
options={{
tabBarLabel: 'Objects',
headerShown: false,
}}
/>
<Tab.Screen
name="Documentation"
component={Documentation}
options={{
tabBarLabel: 'Equipment',
headerShown: false,
}}
/>
</Tab.Navigator>
);
};
export const StackNavigation = () => {
return (
<Stack.Navigator>
<Stack.Screen
name="TabNavigation"
component={TabNavigation}
options={{headerShown: false}}
/>
<Stack.Screen
name="Equipment Details"
component={EquipmentDetails}
options={{title: 'Equipment Details'}}
/>
<Stack.Screen
name="Equipment Details Update"
component={EquipmentDetailsUpdate}
options={{title: 'Equipment Details Update'}}
/>
<Stack.Screen
name="Equipment Details Update Zander"
component={EquipmentDetailsUpdateZander}
options={{title: 'Equipment Details Update Zander'}}
/>
<Stack.Screen name="Objects Details" component={ObjectsDetails} />
<Stack.Screen
name="Objects Details Update"
component={ObjectsDetailsUpdate}
/>
<Stack.Screen
name="Documentation Details"
component={DocumentationDetails}
/>
<Stack.Screen
name="Documentation Details Update"
component={DocumentationDetailsUpdate}
/>
</Stack.Navigator>
);
};
For the current version (v6.x) you can use: tabBarStyle option passing display as none:
tabBarStyle: {
display: 'none'
}
and if you wish to show the tabBar again, just the the display to flex (default value).
I have react native app which I am using react navigation and my navigation stack looks like the following:
<AppStack.Navigator screenOptions={{
headerStyle: {
backgroundColor: COLORS.primary2,
elevation: 0,
shadowOpacity: 0,
},
headerTintColor: '#fff',
}}>
<AppStack.Screen
name="Home"
component={HomeScreen}
options={{
headerShown: false
}}
/>
<AppStack.Screen
name="qr"
component={qr}
options={{
headerShown: false
}} />
<AppStack.Screen
name="Profile"
component={ProfileScreen}
options={{ headerShown: false }}
/>
<AppStack.Screen
name="Notifications"
component={NotificationScreen}
options={{ headerShown: false }}
/>
<AppStack.Screen
name="Support"
component={ChatScreen}
options={{ headerShown: false }}
/>
</AppStack.Navigator>
I want to create createBottomTabNavigator but to be displayed in all screen in the AppStack except the following home screen
<AppStack.Screen
name="Home"
component={HomeScreen}
options={{
headerShown: false
}}
/>
May I know what the best practice to implement that.
You can use tabBarVisible(boolean) prop for this purpose.
<AppStack.Screen
name="Home"
component={HomeScreen}
options={{
headerShown: false
}}
navigationOptions:()=>{
return {
tabBarVisible:false,
}
}
/>
As you can see below, I've tried many ways of setting the background color to green, all to no avail. The background remains blue like the image.
The inactiveColor and activeColor are working (white and red respectively).
<NavigationContainer>
<Tab.Navigator
initialRouteName="HomeScreen"
activeColor="red"
inactiveColor="white"
activeBackgroundColor="green"
inactiveBackgroundColor="green"
style={{ backgroundColor: 'green' }}
tabBarOptions={{
style:{
backgroundColor: 'green'
}
}}
>
<Tab.Screen
name="HomeScreen"
options={{
tabBarLabel: 'Home',
tabBarIcon: ({ color }) => (
<MaterialCommunityIcons name="home" color={color} size={26} />
),
}}
>
{props => <HomeScreen {...props} state={this.state} />}
</Tab.Screen>
<Tab.Screen
name="Files"
component={FilesScreen}
options={{
tabBarLabel: 'Files',
tabBarIcon: ({ color }) => (
<MaterialCommunityIcons name="file" color={color} size={26} />
),
}}
/>
</Tab.Navigator>
</NavigationContainer>
package.json
"dependencies": {
"#react-native-community/masked-view": "^0.1.7",
"#react-navigation/material-bottom-tabs": "^5.1.7",
"#react-navigation/native": "^5.1.4",
}
In React Navigation 6.x, you use tabBarStyle
<Tab.Navigator
screenOptions={({ route }) => ({
headerShown: false,
tabBarStyle: {
height: 90,
paddingHorizontal: 5,
paddingTop: 0,
backgroundColor: 'rgba(34,36,40,1)',
position: 'absolute',
borderTopWidth: 0,
},
})}
>
<Tab.Screen name="Home" component={Home} />
<Tab.Screen name="List" component={RegistrationList} />
<Tab.Screen name="News" component={News} />
<Tab.Screen name="Profile" component={Profile} />
</Tab.Navigator>
in the react-navigation V5 your can to do this:
<Tab.Navigator
initialRouteName={'Critic'}
tabBarOptions={{
activeTintColor: '#fff',
inactiveTintColor: 'lightgray',
activeBackgroundColor: '#c4461c',
inactiveBackgroundColor: '#b55031',
style: {
backgroundColor: '#CE4418',
paddingBottom: 3
}
}}
>
<Tab.Screen name="Critic" component={Critic} options={CriticOptions} />
<Tab.Screen name="Urgent" component={Urgent} options={UrgentOptions} />
<Tab.Screen name="Moderate" component={Moderate} options={ModerateOptions} />
<Tab.Screen name="All" component={All} options={AllOptions} />
</Tab.Navigator>
);
Refer documentation here, You need to use barStyle.
Try
<Tab.Navigator
initialRouteName="Feed"
shifting={true}
labeled={false}
sceneAnimationEnabled={false}
activeColor="#00aea2"
inactiveColor="#95a5a6"
barStyle={{ backgroundColor: '#ffff' }}
You need to add the backgroundColor in screenOptions.
https://reactnavigation.org/docs/bottom-tab-navigator/#screenoptions
Try this:
<Tab.Navigator screenOptions={{
tabBarOptions: {
style: {
backgroundColor: '#f9f9f9',
},
},
}}>
<Navigator
screenOptions={{
tabBarActiveTintColor: theme.colors.main,
tabBarInactiveTintColor: theme.colors.text_detail,
tabBarShowLabel: false,
tabBarStyle: {
paddingVertical: Platform.OS === 'ios' ? 20 : 0,
height: 78,
backgroundColor: theme.colors.background_primary
}
}}
>
<Tab.Navigator
screenOptions={{
tabBarActiveTintColor: "red",
tabBarInactiveTintColor: "blue",
tabBarStyle: {
height: 55,
},
tabBarLabelStyle: {
fontSize: 14,
margin: 0,
},
}}>
you can set the property in tabBarOptions of Tab.Navigator
<Tab.Navigator
screenOptions={({ route }) => ({
....
})}
tabBarOptions={{
activeTintColor: 'tomato',
inactiveTintColor: 'gray',
showLabel: false,
style: {backgroundColor: primaryLighterColor,},
}}
>
you may try this
<Tab.Navigator
screenOptions={{
headerShown: false,
gestureEnabled: true,
gestureDirection: 'horizontal',
tabBarStyle: {
backgroundColor: '#3E48A0',
},
}}>
</Tab.Navigator>