React Navigation how to hide tabbar inside stack navigation - react-native

I'm new to react native, I couldn't do what I wanted to do.
The situation is
When I click the button in the SettingsScreen, I Hide the Bottom Tab, but
The thing I can't understand is,
Is my path and course wrong?
Tab Bottom Height changes, thank you in advance for your help.
import * as React from 'react';
import { getFocusedRouteNameFromRoute } from '#react-navigation/native';
import { createStackNavigator } from '#react-navigation/stack';
import SettingScreen from '../screen/SettingScreen';
import SettingDetails from '../screen/SettingDetails';
const Stack = createStackNavigator();
const tabHiddenRoutes = ['SettingDetails'];
function SettingStack({ navigation, route }) {
React.useLayoutEffect(() => {
if (tabHiddenRoutes.includes(getFocusedRouteNameFromRoute(route))) {
navigation.setOptions({ tabBarStyle: { display: 'none' } });
} else {
navigation.setOptions({ tabBarStyle: { display: 'flex' } });
}
}, [navigation, route]);
return (
<Stack.Navigator
initialRouteName="Setting"
screenOptions={{
headerBackTitleVisible: false,
headerTitleAlign: 'center',
headerStyle: {
backgroundColor: '#5D3EBD',
},
headerTitleStyle: {
color: '#fff',
},
headerBackTitleStyle: {
color: '#fff',
},
headerTintColor: '#fff',
}}>
<Stack.Screen
name="Setting"
component={SettingScreen}
options={{ title: 'Setting Page' }}
/>
<Stack.Screen
name="SettingDetails"
component={SettingDetails}
options={{ title: 'Setting Details' }}
/>
</Stack.Navigator>
);
}
export default SettingStack;
Snack

Related

react-native navigation. Drawer not opening after package update

I am make using react-native. I recently had to update my react-navigation package to version 6. The issue is my drawer will no longer open and I cannot figure out how to fix it.
This is may code for my navigation:
import React from 'react';
import { createDrawerNavigator } from '#react-navigation/drawer';
import { createStackNavigator } from '#react-navigation/stack';
import { StyleSheet, TouchableOpacity } from 'react-native';
import Icon from 'react-native-vector-icons/dist/FontAwesome5';
import IonIcon from 'react-native-vector-icons/dist/Ionicons';
import { useNavigation } from '#react-navigation/native';
import { HomeScreen } from '../../screens/app/home/home.screen';
import HistoryScreen from '../../screens/app/history/history.screen';
import { SignoffScreen } from '../../screens/app/signoff/signoff.screen';
import NotificationsScreen from '../../screens/app/notifications/notifications.screen';
import useTheme from '../../theme/hooks/useTheme';
import { AppStackList, AppStackProps, DrawerList } from './types';
import { Colors } from '../../theme/Variables';
import CustomDrawerContent from '../../components/molecules/custom-drawer';
import { common } from '../../theme/Common';
import { FormScreen } from '../../screens/app/form/form.screen';
import { Menu } from '../../assets';
const AppStack = createStackNavigator<AppStackList>();
const Drawer = createDrawerNavigator<DrawerList>();
const renderIcon = (name: string, ion: boolean) => {
if (ion) {
return <IonIcon name={name} style={styles.iconStyle} />;
}
return <Icon name={name} style={styles.iconStyle} />;
};
const NotificationsNavigator = () => {
const { Gutters } = useTheme();
const navigation = useNavigation<AppStackProps>();
return (
<TouchableOpacity
style={(common.navIconStyle, Gutters.regularRMargin)}
delayPressIn={0}
onPress={navigation.navigate('Notifications', { screen: 'NotificationsScreen' })}
>
<IonIcon name="notifications-outline" style={common.navIconStyle} />
</TouchableOpacity>
);
};
const MenuNavigator = () => {
const navigation = useNavigation<AppStackProps>();
return (
<TouchableOpacity>
<Menu name="notifications-outline" style={common.navIconStyle} />
</TouchableOpacity>
);
};
const historyDrawerOptions = {
headerShown: false,
title: '',
drawerIcon: () => renderIcon('tasks', false),
headerTintColor: Colors.black,
headerRight: NotificationsNavigator,
};
const AppNavigator = () => {
const { Custom } = useTheme();
return (
<AppStack.Navigator screenOptions={Custom.globalNavigatorScreenOptions}>
<AppStack.Screen
name="App Home"
component={DrawerNavigator}
options={{ headerShown: false }}
/>
<AppStack.Screen
name="NotificationsScreen"
component={NotificationsScreen}
options={{ headerShown: false }}
/>
<AppStack.Screen name="FormScreen" component={FormScreen} options={{ headerShown: false }} />
<AppStack.Screen
name="SignoffScreen"
component={SignoffScreen}
options={{ headerShown: false }}
/>
</AppStack.Navigator>
);
};
const DrawerNavigator = () => (
<Drawer.Navigator
drawerStyle={styles.drawerStyle}
drawerContentOptions={{
activeTintColor: Colors.primary,
inactiveTintColor: Colors.white,
labelStyle: {
color: Colors.white,
},
}}
drawerContent={() => <CustomDrawerContent />}
>
<Drawer.Screen
name="Home"
component={HomeScreen}
options={{
headerShown: true,
headerTitle: '',
headerTransparent: true,
headerStyle: {
height: 120,
backgroundColor: '#fff',
},
headerTitleAlign: 'center',
headerTintColor: '#002C5F',
headerRight: NotificationsNavigator,
headerRightContainerStyle: {
width: 100,
marginRight: 8,
},
headerLeft: MenuNavigator,
drawerActiveTintColor: Colors.white,
drawerInactiveTintColor: Colors.white,
drawerLabelStyle: { fontSize: 15 },
}}
/>
<Drawer.Screen name="History" component={HistoryScreen} options={historyDrawerOptions} />
</Drawer.Navigator>
);
export default AppNavigator;
The draw was working before the update but now after it wont open? My NotificationsNavigator will also not open to its screen. Can anyone help???

Use the main App Header for Nested StackNavigation

I'm working on a React Native App, which I have on the main App.js file created a Drawer and a Stack Navigatior, the problem that I'm facing is that when I navigate through the Drawer to the Pages with the Stack Navigation, I get 2 Headers (one below the Other), is there a way to use the same header (top header or Main header) when I get to the Stack Pages.
Here is the App.js code:
import 'react-native-gesture-handler';
import React from 'react';
import { StyleSheet} from 'react-native';
import { NavigationContainer } from '#react-navigation/native';
import { createDrawerNavigator } from '#react-navigation/drawer';
import { createStackNavigator } from '#react-navigation/stack';
//Importacion de Screens
import HomeScreen from './src/screens/HomeScreen';
import DetailsScreen from './src/screens/DetailScreen';
import OrderSearchScreen from './src/screens/OrderSearchScreen';
import OrderNumberScreen from './src/screens/OrderNumberScreen';
const OrderStack = createStackNavigator();
const Drawer = createDrawerNavigator();
const OrderStackScreen = () =>(
<OrderStack.Navigator screenOptions={{
headerStyle: {
backgroundColor: '#009387',
},
headerTintColor: '#fff',
headerTitleStyle:{
fontWeight: 'bold',
} ,
headerTitleStyle: { alignSelf: 'center' },
/*headerShown: false*/
}}>
<OrderStack.Screen name="OrderSearchScreen" component={OrderSearchScreen}/>
<OrderStack.Screen name="OrderNumberScreen" component={OrderNumberScreen}/>
</OrderStack.Navigator>
);
export default function App() {
return (
<NavigationContainer>
<Drawer.Navigator initialRouteName="Home" screenOptions={{
headerStyle: {
backgroundColor: '#009387',
},
headerTintColor: '#fff',
headerTitleStyle:{
fontWeight: 'bold',
} ,
headerTitleStyle: { alignSelf: 'center' },
}}>
<Drawer.Screen name="Home" component={HomeScreen} />
<Drawer.Screen name="Details" component={DetailsScreen} />
<Drawer.Screen name="Orders" component={OrderStackScreen} />
</Drawer.Navigator>
</NavigationContainer>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center',
},
});
Here is what I see inside the Stack:
What I wish to see is that the top Header Changes and the Bottom one never appears, so the Top Header will have the Title of the Page being visited and right next to the Drawer Icon (the 3 lines, I think it is called Hamburger button), I get the Arrow to go back.
Is there a way to do this.
Thanks
Hide the stack header likes this:
<OrderStack.Navigator screenOptions={{ headerShown: false }}>
{/* whatever */}
</OrderStack.Navigator>
Configure the drawer header to show stack's screen name:
import { getFocusedRouteNameFromRoute } from '#react-navigation/native';
// ...
<Drawer.Navigator
initialRouteName="Home"
screenOptions={({ route }) => {
const routeName =
getFocusedRouteNameFromRoute(route) ?? 'OrderSearchScreen';
let headerTitle;
switch (routeName) {
case 'OrderSearchScreen':
headerTitle = 'Search';
break;
case 'OrderNumberScreen':
headerTitle = 'Order no.';
break;
}
return {
headerTitle,
headerShown: true,
headerStyle: { backgroundColor: '#009387' },
headerTintColor: '#fff',
headerTitleStyle: { fontWeight: 'bold' },
headerTitleAlign: 'center',
};
}}
>
{/* whatever */}
</Drawer.Navigator>;
Docs: https://reactnavigation.org/docs/screen-options-resolution/#setting-parent-screen-options-based-on-child-navigators-state
If you want to show both hamburger menu and back icon, you need to use headerLeft to override the default one. Though it's very unusual to show both at once.

React Native Screen white blinking when moving between tabs

im working on a App and im Using a BottomTabBar and in there are StackNavigators. When i switch the screens the screens gets white, it seems like they are loading. but i just want it without a loading animation or transition. i just want it like whatsapp or instagram so i can swap between my screens but i need a header for my application.
import React from "react";
import News from "../screens/News";
import Favorites from "../screens/Favorites";
import NewRecipe from "../screens/NewRecipe";
import Ingredients from "../screens/Ingredients";
import Profile from "../screens/Profile";
import { NavigationContainer } from "#react-navigation/native";
import { createMaterialBottomTabNavigator } from "#react-navigation/material-bottom-tabs";
import { MaterialIcons } from "#expo/vector-icons";
import { SafeAreaView } from "react-native-safe-area-context";
import { createStackNavigator } from "#react-navigation/stack";
export default function AppScreen() {
const Tab = createMaterialBottomTabNavigator();
const NewsStack = createStackNavigator();
const FavoritesStack = createStackNavigator();
const NewRecipeStack = createStackNavigator();
const IngredientsStack = createStackNavigator();
const ProfileStack = createStackNavigator();
function NewsNav() {
return (
<NewsStack.Navigator
screenOptions={{
animationEnabled: false,
}}
>
<NewsStack.Screen
name="News"
component={News}
options={{
headerTintColor: "#277093",
headerStyle: {
backgroundColor: "#272727",
height: 75,
},
headerTitleStyle: {
marginTop: -15,
},
animationEnabled: false,
}}
/>
</NewsStack.Navigator>
);
}
function FavoritesNav() {
return (
<FavoritesStack.Navigator>
<FavoritesStack.Screen
name="Favoriten"
component={Favorites}
options={{
headerTintColor: "#277093",
headerStyle: {
backgroundColor: "#272727",
height: 75,
},
headerTitleStyle: {
marginTop: -15,
},
}}
/>
</FavoritesStack.Navigator>
);
}
function NewRecipeNav() {
return (
<NewRecipeStack.Navigator
screenOptions={{
cardStyle: {
opacity: 1,
},
}}
>
<NewRecipeStack.Screen
name="Neue Rezepte"
component={NewRecipe}
options={{
headerTintColor: "#277093",
headerStyle: {
backgroundColor: "#272727",
height: 75,
},
headerTitleStyle: {
marginTop: -15,
},
}}
/>
</NewRecipeStack.Navigator>
);
}
function IngredientsNav() {
return (
<IngredientsStack.Navigator>
<IngredientsStack.Screen
name="Zutaten"
component={Ingredients}
options={{
headerTintColor: "#277093",
headerStyle: {
backgroundColor: "#272727",
height: 75,
},
headerTitleStyle: {
marginTop: -15,
},
}}
/>
</IngredientsStack.Navigator>
);
}
function ProfileNav() {
return (
<ProfileStack.Navigator>
<ProfileStack.Screen
name="Profil"
component={Profile}
options={{
headerTintColor: "#277093",
headerStyle: {
backgroundColor: "#272727",
height: 75,
},
headerTitleStyle: {
marginTop: -15,
},
}}
/>
</ProfileStack.Navigator>
);
}
return (
<NavigationContainer>
<Tab.Navigator
screenOptions={({ route }) => ({
tabBarIcon: ({}) => {
let iconName;
if (route.name == "News") {
iconName = "language";
} else if (route.name == "Favoriten") {
iconName = "star-border";
} else if (route.name == "Hinzufügen") {
iconName = "add-circle-outline";
} else if (route.name == "Zutaten") {
iconName = "shopping-cart";
} else if (route.name == "Profil") {
iconName = "person";
}
return (
<MaterialIcons
name={iconName}
color={"#277093"}
size={25}
></MaterialIcons>
);
},
})}
tabBarOptions={{
activeTintColor: "green",
}}
barStyle={{ backgroundColor: "#272727" }}
>
<Tab.Screen
name="News"
component={NewsNav}
options={{ animationEnabled: false }}
/>
<Tab.Screen name="Favoriten" component={FavoritesNav} />
<Tab.Screen name="Hinzufügen" component={NewRecipeNav} />
<Tab.Screen name="Zutaten" component={IngredientsNav} />
<Tab.Screen name="Profil" component={ProfileNav} />
</Tab.Navigator>
</NavigationContainer>
);
}
nsition but i cant fix it
Lower react-native-screen package version to 2.18.1 . Solution was obtained from this discussion.
https://github.com/react-navigation/react-navigation/issues/9593
Other solutions like setting the theme in Navigation Container, setting the cardInterpolatorStyle, and other modifications to the screen options of the navigator did not work.
This issue was visible only on Android in my case.

props.navigation when component is not part of stack navigator

I have a stackNavigator and DrawerNavigator defined in AppNavigator.js file. It is then imported by App. In AppNavigator, I have a drawer icon to open the sidebar but I can't open it yet because navigate don't exist. I can't pass navigation to AppNavigator sine App component is not part of the stack navigator. I am trying to contain my navigation in one file and still be able to open/close my drawer bar from there. Any help?
AppNavigator.js:
import React from 'react';
import { createAppContainer, createSwitchNavigator } from 'react-navigation';
import { createStackNavigator } from 'react-navigation-stack';
import ScreenHome from './screens/member/ScreenHome';
import { createDrawerNavigator } from 'react-navigation-drawer';
import Icon from "react-native-vector-icons/Ionicons";
const authenicatedNavigation = createStackNavigator(
{
Home: {
screen: ScreenHome,
navigationOptions: ({ navigation }) => ({
title: "Home",
drawerLabel: "Home"
})
}
},
{
initialRouteName: "Home",
headerMode: "screen",
defaultNavigationOptions: {
headerStyle: {
backgroundColor: '#ffffff',
elevation: 0,
shadowOpacity: 0
},
headerTintColor: '#333333',
headerTitleStyle: {
fontWeight: 'bold',
color: '#ffffff'
},
headerLeft: (
<Icon
style={{paddingLeft: 10, color:'white'}}
onPress={()=> navigation.openDrawer()} //-----undefined navigation
name="md-menu"
size={30}
/>
)
}
}
)
const MainDrawer = createDrawerNavigator(
{
MainTabs: authenicatedNavigation,
},
{
hideStatusBar : false,
drawerBackgroundColor: 'rgba(255,255,255,0)',
overlayColor : '#f68873',
contentOptions: {
activeTintColor: '#fff',
activeBackgroundColor: '#6b52ae'
}
}
);
const App = createSwitchNavigator({
App: {
screen: MainDrawer,
}
});
const AppNavContainer = createAppContainer(
App,
{
initialRouteName: 'App',
}
);
export default AppNavContainer;
App.js:
import React , {Component} from 'react';
import { StyleSheet, View } from 'react-native';
import AppNavContainer from './AppNavigator';
import NavigationService from './shared/NavigationService';
import {axios} from './shared/httpinterceptor';
export default class App extends Component {
constructor(){
super();
}
render() {
return (
<View>
<AppNavContainer
ref={navigatorRef => {
NavigationService.setTopLevelNavigator(navigatorRef);
}}
/>
</View>
);
}
}
Currently, in ScreenHome file, I can open the drawer by:
<Button onPress={this.props.navigation.openDrawer} title="Open"/>
Given I have no access to props.navigation in Apps, how do I open the drawer from AppNavigator?
defaultNavigationOptions (as well as navigationOptions) can be defined as a function which receives the navigation instance as parameter, so you'd just need to update your defaultNavigationOptions as follows:
defaultNavigationOptions: ({navigation}) => ({
headerStyle: {
backgroundColor: '#ffffff',
elevation: 0,
shadowOpacity: 0
},
headerTintColor: '#333333',
headerTitleStyle: {
fontWeight: 'bold',
color: '#ffffff'
},
headerLeft: (
<Icon
style={{paddingLeft: 10, color:'white'}}
onPress={()=> navigation.openDrawer()}
name="md-menu"
size={30}
/>
)
})

Header is not showing in react-navigation-drawer React-Native

I am implementing react-navigation-drawer from React Navigation Library. But facing problem related to header. The header bar is not showing in any of the screens.
This is my App.js
import React from "react";
import { StyleSheet, ScrollView, View } from "react-native";
//import DrawerNavigator from "./navigation/DrawerNavigator";
import { Platform, Dimensions } from "react-native";
import { createAppContainer } from "react-navigation";
import { createDrawerNavigator } from "react-navigation-drawer";
import Home from "./components/home";
import Contact from "./components/contact";
const WIDTH = Dimensions.get("window").width;
const RouteConfigs = {
Home: {
screen: Home
},
Contact: {
screen: Contact
}
};
const DrawerNavigatorConfig = {
drawerWidth: WIDTH * 0.75,
drawerType: "both",
initialRouteName: "Home"
};
const DrawerNavigator = createDrawerNavigator(
RouteConfigs,
DrawerNavigatorConfig
);
const MyApp = createAppContainer(DrawerNavigator);
export default class App extends React.Component {
render() {
return <MyApp />;
}
}
And this is my home screen
import React, { Component } from "react";
import { View, Image, Text, StyleSheet, ScrollView } from "react-native";
import { FontAwesomeIcon } from "#fortawesome/react-native-fontawesome";
import { faTruck, faHome } from "#fortawesome/free-solid-svg-icons";
class Home extends Component {
static navigationOptions = {
headerTitle: "Home",
drawerIcon: ({ tintColor }) => <FontAwesomeIcon size={25} icon={faHome} />
};
render() {
return (
<View style={{ flex: 1, alignItems: "center", justifyContent: "center" }}>
<Text>Home Screen</Text>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: "#F5F5F5",
flexDirection: "column"
},
icon: {
width: 24,
height: 24
}
});
export default Home;
Can anyone help me. Thanks in advance!!!
#hongdeveloper this is a simple example solution for react navigation 5:
function Root() {
return (
<Stack.Navigator>
<Stack.Screen options={{title: "Profile"}} name="Profile" component={Profile} />
<Stack.Screen options={{title: "Settings"}} name="Settings" component={Settings} />
</Stack.Navigator>
);
}
function App() {
return (
<NavigationContainer>
<Drawer.Navigator>
<Drawer.Screen name="Home" component={Home} />
<Drawer.Screen name="Root" component={Root} />
</Drawer.Navigator>
</NavigationContainer>
);
}
You can find about the navigation to a screen in a nested navigator in docs and you can try this example on Snack
The drawer navigator does not contain headers. Stack navigators must be configured to display headers.
const DrawerNavigator = createDrawerNavigator(
RouteConfigs,
DrawerNavigatorConfig
);
const Root = createStackNavigator({
Main: { screen : DrawerNavigator}
},
{
defaultNavigationOptions : ({ navigation }) => ({
title: "Screen"
})
})
const Stacks = createAppContainer(Root)
export default Stacks;
Since December 2020 you can now use the headerShown: true setting in screenOptions of your Drawer.Navigator to show the header in React Navigation 5.
See more about this issue here: https://github.com/react-navigation/react-navigation/issues/1632
See the commit and comments about the new feature in React Navigation 5 here
https://github.com/react-navigation/react-navigation/commit/dbe961ba5bb243e8da4d889c3c7dd6ed1de287c4
Late reply, But I did it with the below code.
I created separate stack navigators for each screen and after that added all the stack navigators in the drawer navigator.
The good thing is it is fully customized.
Please see my code below.
const WIDTH = Dimensions.get('window').width;
const HomeNavigator = createStackNavigator(
{
Home: Home
},
{
defaultNavigationOptions: ({ navigation }) => {
return {
headerStyle: {
backgroundColor: '#1e89f4'
},
headerTitle: 'Knowledge Woledge',
headerTintColor: '#fff',
headerTitleStyle: {
fontWeight: 'bold',
textAlign: 'center',
flex: 1
},
headerLeft: (
<View style={{ paddingLeft: 13 }}>
<FontAwesomeIcon
size={25}
color='#fff'
icon={faBars}
onPress={() => navigation.openDrawer()}
/>
</View>
),
headerRight: <View />
};
}
}
);
const DetailNavigator = createStackNavigator(
{
PostDetail: PostDetail
},
{
defaultNavigationOptions: ({ navigation }) => {
return {
headerStyle: {
backgroundColor: '#1e89f4'
},
headerTitle: () => {
return (
<Text
style={{
color: '#fff',
fontWeight: 'bold',
textAlign: 'center',
flex: 1,
fontSize: 20
}}
>
{navigation.getParam('headerTitle')}
</Text>
);
},
headerTintColor: '#fff',
headerTitleStyle: {
fontWeight: 'bold',
textAlign: 'center',
flex: 1
},
headerLeft: (
<View style={{ paddingLeft: 13 }}>
<FontAwesomeIcon
size={25}
color='#fff'
icon={faArrowLeft}
onPress={() => navigation.goBack(null)}
/>
</View>
),
headerRight: <View />
};
}
}
);
Assigned this in a const
const RouteConfigs = {
Home: {
screen: HomeNavigator,
navigationOptions: {
drawerLabel: 'Home',
drawerIcon: ({ tintColor }) => (
<FontAwesomeIcon size={20} color={tintColor} icon={faHome} />
)
}
},
Detail: {
screen: DetailNavigator,
navigationOptions: {
drawerLabel: () => {
return null;
}
}
}
};
And finally, create a drawer navigator with this.
const DrawerNavigatorConfig = {
drawerWidth: WIDTH * 0.75,
drawerType: 'both',
initialRouteName: 'Home'
};
const DrawerNavigator = createDrawerNavigator(
RouteConfigs,
DrawerNavigatorConfig
);
const Stacks = createAppContainer(DrawerNavigator);
export default Stacks;