react-navigation: header above tab nav - react-native

I'm trying to get the Recipes header in the following image to display above the tab navigator (home and settings in the image below). Currently I have the tab navigator in a stack navigator. On the stack navigator I defined a title and headerTitle but neither are displaying. How can I get the header above? Thanks!
This is what it looks like currently:
I want to achieve something similar to this:
This is my stack nav code:
<NavigationContainer>
<Tab.Navigator
shifting={false}
labeled={false}
initialRouteName="Home"
activeColor="#32CA81"
barStyle={styles.navContainer}
screenOptions={{
headerShown: false,
}}
tabBarOptions={{
activeTintColor: '#e91e63',
}}
>
<Tab.Screen
name="Camera"
component={Camera}
options={{
tabBarLabel: "Camera",
tabBarIcon: ({ color }) => (
<MaterialIcons name="camera-alt" color={color} size={26} />
),
}}
/>
<Tab.Screen
name="Home"
component={Home}
options={{
title: "Recipes",
headerTitle: "Recipes",
tabBarLabel: "Recipes",
tabBarIcon: ({ color }) => (
<MaterialIcons name="restaurant-menu" color={color} size={26} />
),
}}
/>
<Tab.Screen
name='Saved'
component={SavedScreen}
options={{
shifting: true,
tabBarLabel: 'Saved',
tabBarIcon: ({color}) => (
<MaterialIcons name='favorite' color={color} size={26} />
),
}}
/>
</Tab.Navigator>
</NavigationContainer>
This is my tab nav code:
return (
<Tab.Navigator>
<Tab.Screen name="Home" component={Recipes} />
<Tab.Screen name="Settings" component={Recipes} />
</Tab.Navigator>
);

I ended up wrapping the component with the tabs, with a stack navigator. I put the text component and tabs on the same stack screen.

Related

Turning off the drawer header in a specific screen in bottom tab navigation in drawer navigation in react native

I have a very big problem I am using two navigations in one app the first one is the drawer navigator this is how I use the drawer navigator:
<Drawer.Navigator
screenOptions={{
drawerStyle: {
backgroundColor: 'white',
},
}}
drawerContent={props => <CustomSidebarMenu {...props} />}
drawerContentOptions={{
activeTintColor: '#e91e63',
activeBackgroundColor: 'red',
itemStyle: {marginVertical: 20},
}}>
<Drawer.Screen
options={{
headerShown: true,
headerTitle: () => (
<Image
style={{height: 150, width: 100, resizeMode: 'contain'}}
source={require('../assets/images/referans2.png')}
/>
), // Title to appear in the header
headerRight: ({navigation, scene}) => (
// Custom component to appear on the right side of the header
<View style={{flexDirection: 'row'}}>
<Pressable>
<Ionicons
name="notifications-outline"
size={30}
color={'black'}
/>
</Pressable>
<Pressable style={{marginHorizontal: 10}}>
<Ionicons
name="chatbubbles-outline"
size={30}
color={'black'}
/>
</Pressable>
</View>
),
}}
name="Ana Sayfa"
component={Main}
/>
<Drawer.Screen
options={{headerShown: true}}
name="Şiparişlerim"
component={MyOrders}
/>
<Drawer.Screen name="Adreslerim" component={AddressesScreen} />
<Drawer.Screen name="Üyelik Bilgilerim" component={AccountInfoScreen} />
</Drawer.Navigator>
[
and this gives me the following output:](https://i.stack.imgur.com/73o8f.png)
In the main function you see here, the bottomtabnavigator, which I use in the whole app, returns.:
const Main = () => {
return (
<Tab.Navigator screenOptions={screenOptions}>
<Tab.Screen
component={HomeStack}
name="Ana Sayfa"
options={{
tabBarIcon: ({focused, color}) => (
<Ionicons name="home-outline" size={28} color={color} />
),
}}
/>
<Tab.Screen
component={CategoriesStack}
name="Kategoriler"
options={{
tabBarIcon: ({focused, color}) => (
<Ionicons name="grid-outline" size={28} color={color} />
),
}}
/>
<Tab.Screen
component={CartStack}
name="Sepet"
options={{
tabBarIcon: ({focused, color}) => (
<Ionicons name="cart-outline" size={28} color={color} />
),
}}
/>
<Tab.Screen
component={DiscoverStack}
name="Keşfet"
options={{
tabBarIcon: ({focused, color}) => (
<Ionicons name="compass-outline" size={28} color={color} />
),
}}
/>
<Tab.Screen
component={ProfileStack}
name="Profilim"
options={{
headerShown: true,
tabBarIcon: ({focused, color}) => (
<Ionicons name="person-circle-outline" size={28} color={color} />
),
}}
/>
</Tab.Navigator>
);
};
What I want is this; Turning off the header of the drawer in the profile stack in the bottom tab navigator, but I can't do it
but it still didn't close the header of the drawer navigation. Even if I set the headershown of the drawer to false, the header on all screens closes, I'm just not on the screen I want
As far as I understand, there are 3 nested navigator.
Drawer
|---------> BottomTab
| |---------> ProfileStack
|... |...
If you want to hide or show only specific screen you can use navigation.setOptions()
For example,we have a Profile screen in ProfileStack and get navigation with screen props or useNavigation()
If you want to hide ProfileStack header in Profile:
React.useLayoutEffect(() => {
navigation.setOptions({ headerShown:false })
})
If you want to hide BottomTab header in Profile:
React.useLayoutEffect(() => {
navigation.getParent().setOptions({ headerShown:false })
})
If you want to hide Drawer header in Profile:
React.useLayoutEffect(() => {
navigation.getParent().getParent().setOptions({ headerShown:false })
})
You can use setOptions with headerShown:true when the drawer screenOptions headerShown:false
react-navigation getParent() and setOptions() docs

React navigation initialRouteName property not working as expected

In my react native app I nested stack navigation inside the tab navigation.
I can't access the screen that I set as an initial route in stack navigation.
The tab navigation component is
<Tab.Navigator initialRouteName='HomeNav' >
<Tab.Screen name="HomeNav" component={HomeNav}
options={{
tabBarIcon: ({ color, size }) => (
<FIcon name="home" color={color} size={size} />
),
}}
/>
<Tab.Screen name="Search" component={Search}
options={{
tabBarIcon: ({ color, size }) => (
<FIcon name="search" color={color} size={size} />
)
}}
/>
<Tab.Screen name="Cart" component={Cart}
options={{
tabBarIcon: ({ color, size }) => (
<MCIcon2 name="cart" color={color} size={size} />
)
}}
/>
<Tab.Screen name="AccountNav" component={AccountNav}
options={{
tabBarIcon: ({ color, size }) => (
<MCIcon2 name="account" color={color} size={size} />
)
}}
/>
</Tab.Navigator >
And here is the account navigation component
const AccountNav = () => {
return (
<Stack.Navigator
initialRouteName="Account"
screenOptions={{
headerShown: false
}}
>
<Stack.Screen name="Account" component={Account} />
<Stack.Screen name="MyOrders" component={MyOrders} />
<Stack.Screen name="Profile" component={Profile} />
</Stack.Navigator>
);
when I try to navigate to MyOrders screen from the other screens. it gets stuck and cannot access the initial route screen (Account).
I had this issue aswell, I solved it by adding lazy: false to the tab navigators screenOptions prop.
screenOptions={{
headerShown: false,
lazy: false
}}
Documentation says that "Routes are lazily initialized -- their screen components are not mounted until they are first focused.", my guess is that the initial route you specify won't "register" until the screen's components are properly mounted (until the screen is focused), so when you go to your AccountNav, the initial route becomes the one you navigated too, bypassing the prop.
The issue with this is that you're mounting all the screen components from all the screens and that may impact performance depending on your application I guess

React Native Tab Navigator

I am totally new to React Native and I am currently trying show BottomTabNavigator on child/details page, for example:
I have a page called Training and I have another page called TrainingDetails.
I wanna show BottomTabNavigator on TrainingDetails.
On truth, I wanna show BottomTabNavigator in all pages, main pages and detail pages.
Here is my Main.js
Thanks so much!
const Tab = createBottomTabNavigator();
return (
<Tab.Navigator tabBarOptions={{ activeTintColor: theme.colors.primary, inactiveTintColor: theme.colors.neutral_100, style: {backgroundColor: theme.colors.active} }}>
<Tab.Screen
options={{
title: "Trabalhar",
tabBarIcon: ({ focused, color, size }) => (
<MaterialIcon name={"headset"} size={size} color={color} />
),
}}
name="Home"
component={HomeScreen}
/>
<Tab.Screen
options={{
title: "Estudar",
tabBarIcon: ({ focused, color, size }) => (
<SimpleLineIcon name={"graduation"} size={size} color={color} />
),
}}
name="Study"
component={Training}
/>
<Tab.Screen
options={{
title: "Notificações",
tabBarIcon: ({ focused, color, size }) => (
<MaterialIcon name={"bell-outline"} size={size} color={color} />
),
}}
name="Notification"
component={HomeScreen}
/>
<Tab.Screen
options={{
title: "Resultados",
tabBarIcon: ({ focused, color, size }) => (
<MaterialIcon name={"trending-up"} size={size} color={color} />
),
}}
name="Results"
component={HomeScreen}
/>
<Tab.Screen
options={{
title: "Carteira",
tabBarIcon: ({ focused, color, size }) => (
<MaterialIcon name={"wallet-outline"} size={size} color={color} />
),
}}
name="Wallet"
component={HomeScreen}
/>
</Tab.Navigator>
);
};
export default Main;
You can put a stackNavigator inside a tab navigator, so for example if you want a home screen and then another screen called details that doesn't have a tab at the bottom but still has the tabs at the bottom you can replace the home screen with a homeStack that has both a home screen and details screen inside it.
const Stack = createStackNavigator();
function HomeStack() {
return (
<Stack.Navigator>
<Stack.Screen name="Home" component={Home} />
<Stack.Screen name="Details" component={Details} />
</Stack.Navigator>
);
}
and then replace your home component in the tab navigator with HomeStack component.

React Native how to programmatically navigate to a stack screen that is on a tab navigator

I have searched tirelessly for an answer to this issue.
I have a Tab Navigator:
const AppNavigator = () => {
return (
<Tab.Navigator initialRouteName="Search">
<Tab.Screen
name="Home"
children={() => <HomeScreen />}
options={{
tabBarIcon: ({ color, size }) => (
<MaterialCommunityIcons name="home" color={color} size={size} />
),
}}
/>
<Tab.Screen
name="Search"
children={() => <SearchContainerNavigator />}
options={{
tabBarIcon: ({ color, size }) => (
<FontAwesome5 name="search" color={color} size={size} />
),
}}
/>
<Tab.Screen
name="Feedback"
children={() => <FeedbackScreen />}
options={{
tabBarIcon: ({ color, size }) => (
<MaterialCommunityIcons name="email" color={color} size={size} />
),
}}
/>
</Tab.Navigator>
);
};
And this Stack navigator:
const SearchContainerNavigator = () => (
<Stack.Navigator screenOptions={{ headerShown: false}} initialRouteName="SearchSelect">
<Stack.Screen name="SearchSelect" component={SearchSelectScreen} />
<Stack.Screen name="AircraftSearch" component={AircraftSearchScreen} />
<Stack.Screen name="AircraftResults" component={AircraftResultsScreen} />
<Stack.Screen name="AircraftDetail" component={AircraftDetailScreen} />
<Stack.Screen name="BrandSearch" component={BrandSearchScreen} />
<Stack.Screen name="BrandResults" component={BrandResultsScreen} />
<Stack.Screen name="BrandDetail" component={BrandDetailScreen} />
<Stack.Screen name="Favourites" component={FavouritesScreen} />
</Stack.Navigator>
)
My issue is how do I programmatically navigate from HomeScreen tab to the AircraftDetailsScreen on the Search Tab??
Thanks in advance.
EDIT:
HomeScreen is a class.
handleAircraftSelect = (aircraft_id) => {
this.props.navigation.navigate("Search", {
screen: "AircraftDetail",
params: { id: aircraft_id },
});
};
navigation.navigate('Search', {screen: 'AircraftDetail'});
https://reactnavigation.org/docs/nesting-navigators/#navigating-to-a-screen-in-a-nested-navigator
For react-navigation 6.x you can use this like below:
navigation.jumpTo('Profile', { name: 'Michaś' });

React native i cannot add a new screen without adding it to createMaterialBottomTabNavigator

Hello i want to be able to go to a new page without adding them to <Tab.Screen by another meaning i want to use this.props.navigation.navigate so in order for me to do that i need to add the new screen but how i can add a new screen without adding them to <tab.screen
this is a small sample of my code
const Tab = createMaterialBottomTabNavigator();
const Stack = createStackNavigator();
const App = ({navigation}) => {
return (
<NavigationContainer>
<Tab.Navigator initialRouteName="Home" shifting={true}>
<Tab.Screen
name="Feed"
component={mainPage}
options={{
tabBarLabel: 'Home',
tabBarColor: '#29a8ab',
tabBarIcon: ({color}) => (
<Icon name="home" color={color} size={26} />
),
}}
tabBarColor={'#FF0000'}
/>
<Tab.Screen
name="Notifications"
component={cartPage}
options={{
tabBarLabel: 'Shop',
tabBarColor: '#ff8b94',
tabBarIcon: ({color}) => (
<Icon name="cart" color={color} size={26} />
),
}}
/>
</Tab.Navigator>
</NavigationContainer>
);
};
export default createApp;