Delayed rendering of parent Drawer header inside Bottom Tab - react-native

I have BottomTab navigator with 2 screens Home and Activity, nested inside a Drawer Navigator. When I switch from one screen to second one using BottomTab, my header of Drawer Navigator hides with flickering effect and same thing happens again when I show it up on previous screen. I am handling headerShown:true and headerShown:false in listeners prop of Tab.Screen using focus and blur of that screen.
It seems like header is rendering after rendering of components below it. This header showing and hiding has more delay if I have multiple components inside both screens.
Snack repo is attached.
https://snack.expo.dev/#a2nineu/bottomtab-inside-drawer

I suggest you use Interaction Manager
As react-native is single threaded, JS gets blocked while running animation which can cause UI to lag and jitter.
Attaching code with changes
import 'react-native-gesture-handler';
import * as React from 'react';
import {
Text,
View,
StyleSheet,
Image,
InteractionManager,
} from 'react-native';
import Constants from 'expo-constants';
import { NavigationContainer } from '#react-navigation/native';
import { createDrawerNavigator } from '#react-navigation/drawer';
import { createMaterialBottomTabNavigator } from '#react-navigation/material-bottom-tabs';
const Drawer = createDrawerNavigator();
const Tab = createMaterialBottomTabNavigator();
const Home = (props) => {
React.useEffect(() => {
const interactionPromise = InteractionManager.runAfterInteractions(() =>
setShowContent(true)
);
return () => interactionPromise.cancel();
}, []);
const [showContent, setShowContent] = React.useState(false);
return showContent ? (
<View>
<Text>Home</Text>
<Image
source={{
uri: 'https://images.unsplash.com/photo-1596265371388-43edbaadab94?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=687&q=80',
}}
style={{ height: 500, width: 500 }}
resizeMode={'cover'}></Image>
</View>
) : null;
};
const Activity = () => {
return <Text>Activity</Text>;
};
const BottomTab = () => {
return (
<Tab.Navigator>
<Tab.Screen name="Home" component={Home} />
<Tab.Screen
name="Activity"
component={Activity}
listeners={({ navigation, route }) => ({
focus: () => {
navigation.getParent().setOptions({
headerShown: false,
});
},
blur: () => {
navigation.getParent().setOptions({
headerShown: true,
});
},
})}
/>
</Tab.Navigator>
);
};
export default function App() {
return (
<View style={styles.container}>
<NavigationContainer>
<Drawer.Navigator screenOptions={{ headerMode: 'float' }}>
<Drawer.Screen
options={{ headerStyle: { height: 100 } }}
name="BottomTab"
component={BottomTab}
/>
</Drawer.Navigator>
</NavigationContainer>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
paddingTop: Constants.statusBarHeight,
backgroundColor: '#ecf0f1',
padding: 8,
},
paragraph: {
margin: 24,
fontSize: 18,
fontWeight: 'bold',
textAlign: 'center',
},
});

Related

React-Native Paper Drawer.Navigator is invisible when Appbar has Appbar.Actions

I have a fairly simple React Native app that I am using to showcase a custom component library. I recently upgraded the app from React Native version 0.67.2 to 0.70.6. React Navigation is still on version 5.x (latest is 6.x). My issue is that when I attempt to open my navigation drawer, I see a shadow over my home screen, but the drawer does not appear. The ellipsis menu also fails to appear.
Here is the home screen on app load:
Here is the home screen when I tap the hamburger menu:
I have narrowed down the problem to my custom header component. When I comment out the Actions in the header, including the children, the drawer works.
Here is the home page:
HomeStack.tsx:
import { CustomHeader } from '#custom-components/Header';
import { createStackNavigator } from '#react-navigation/stack';
import React from 'react';
import { Appbar, Menu, Divider, useTheme } from 'react-native-paper';
import { HomeScreen } from '../screens';
const Stack = createStackNavigator();
const HomeStack = (): JSX.Element => {
const theme: ReactNativePaper.Theme = useTheme();
const [isMenuVisible, setMenuVisible] = React.useState(false);
const openMenu = () => setMenuVisible(true);
const closeMenu = () => setMenuVisible(false);
return (
<Stack.Navigator
headerMode="float"
screenOptions={{
header: () => (
<CustomHeader title="Home">
<Menu
visible={isMenuVisible}
onDismiss={closeMenu}
anchor={
<Appbar.Action
icon="dots-vertical"
testID="header-action-1"
touchSoundDisabled={false}
onPress={openMenu}
color={theme.colors.text}
/>
}
>
<Menu.Item onPress={() => {}} title="Item 1" />
<Menu.Item onPress={() => {}} title="Item 2" />
<Menu.Item onPress={() => {}} title="Item 3" />
</Menu>
</CustomHeader>
),
}}
>
<Stack.Screen name="Home" component={HomeScreen} />
</Stack.Navigator>
);
};
export default HomeStack;
And the header:
CustomHeader.tsx
import { DrawerActions, useNavigation } from '#react-navigation/native';
import React from 'react';
import { Platform, StyleSheet, View } from 'react-native';
import { Appbar, useTheme } from 'react-native-paper';
import { common } from '../theme/colors';
export type CustomHeaderProps = {
title: string;
subtitle?: string;
scaleMenuIcon?: number;
headerHeight?: number;
titleSize?: number;
subtitleSize?: number;
children?: React.ReactNode;
backgroundColor?: string;
color?: string;
};
export const CustomHeader = ({
title,
subtitle,
scaleMenuIcon,
titleSize = 20,
subtitleSize = 15,
headerHeight,
children,
backgroundColor = common.offWhite,
color = common.black,
}: CustomHeaderProps): JSX.Element => {
const navigation = useNavigation();
const theme = useTheme();
const openMenu = () => {
navigation.dispatch(DrawerActions.openDrawer());
};
return (
<Appbar.Header style={
backgroundColor: theme.dark ? undefined : backgroundColor,
height: headerHeight
}>
<Appbar.Action
icon="menu"
testID="header-button"
style={styles.menuIcon}
onPress={openMenu}
touchSoundDisabled={true}
size={scaleMenuIcon}
color={theme.dark ? undefined : color}
/>
<Appbar.Content
testID="appbar-content"
color={theme.dark ? undefined : color}
style={styles.headerText}
title={title}
titleStyle={{ fontSize: titleSize }}
subtitle={subtitle}
subtitleStyle={{ fontSize: subtitleSize }}
/>
// If I comment out this View, the drawer appears.
<View style={styles.headerImageText}>
{children && (
<View testID="appbar-actions" style={styles.children}>
{children}
</View>
)}
</View>
</Appbar.Header>
);
};
const styles = StyleSheet.create({
children: {
flexDirection: 'row',
justifyContent: 'flex-end',
paddingRight: 30,
...Platform.select({
ios: {
left: -10,
},
android: {
left: 0,
},
}),
},
headerImageText: {
alignItems: 'center',
flexDirection: 'row',
justifyContent: 'flex-start',
paddingLeft: 10,
},
headerText: {
flexGrow: 6,
flexShrink: 1,
fontSize: 20,
fontWeight: 'bold',
justifyContent: 'center',
left: -10,
letterSpacing: 1,
},
menuIcon: {
left: 10,
},
});

React Native, how to import navigation container?

My idea is to have nav.js contain the navigation container for my mobile application, along with all of the screens here (i.e. the homescreen). This file would theoretically let me include buttons in another file that would let me navigate to the screen in the nav.js file that I specified with the button.
I made a constant for this called NavBar and exported it, but when I tried to import into my photo.js file (an example file where I want to include a button that lets me navigate to my 'Tasks' screen), I got the error:
Error: Looks like you have nested a 'NavigationContainer' inside another. Normally you need only one container at the root of the app, so this was probably an error. If this was intentional, pass 'independent={true}' explicitly. Note that this will make the child navigators disconnected from the parent and you won't be able to navigate between them.
I tried simply making my own button in photo.js instead of :
<Button title="Go to tasks" color="lightblue" onPress={() => navigation.navigate('Tasks')}/>, but that only gave me the error that the variable navigation could not be found.
nav.js
import React from 'react';
import { NavigationContainer } from '#react-navigation/native';
import { createNativeStackNavigator } from '#react-navigation/native-stack';
import { StyleSheet, View, Button, ScrollView } from 'react-native';
import TaskApp from './taskapp';
import AddTank from './tank';
const NavBar = () => {
const Stack = createNativeStackNavigator();
{/* Homescreen */}
const HomeScreen = ( {navigation} ) => {
return (
<ScrollView style={homeStyle.container}>
<AddTank />
<Button title="Go to tasks" color="lightblue" onPress={() => navigation.navigate('Tasks')}/>
</ScrollView>
)
}
{/* Default config */}
const Config = ( {navigation } ) => {
return (
<View></View>
)
}
return (
<NavigationContainer>
<Stack.Navigator initialRouteName='Home'>
<Stack.Screen name="Home" component={HomeScreen}/>
<Stack.Screen name="Tasks" component={TaskApp}/>
<Stack.Screen name="Config" component={Config}/>
</Stack.Navigator>
</NavigationContainer>
)
}
const homeStyle = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#E8EAED',
},
tasks: {
flex: 1,
height: 30,
width: 30,
backgroundColor: '#E8EAED',
},
});
export default NavBar;
photo.js
import React, {useState, useEffect} from 'react';
import { StyleSheet, Text, View, Button, Image, ImageBackground } from 'react-native';
import { NavigationContainer, StackActions } from '#react-navigation/native';
import { createNativeStackNavigator } from '#react-navigation/native-stack';
import * as ImagePicker from 'expo-image-picker';
import NavBar from './nav';
const AddPhoto = () => {
const add = {uri: 'https://media.discordapp.net/attachments/639282516997701652/976293252082839582/plus.png?width=461&height=461'}
const Stack = createNativeStackNavigator();
const [hasGalleryPermission, setHasGalleryPermission] = useState(null);
const[ image, setImage ] = useState(null);
useEffect(() => {
(async () => {
const galleryStatus = await ImagePicker.requestCameraMediaLibraryPermissionAsync();
setHasGalleryPermission(galleryStatus.status === 'granted');
})();
}, []);
const pickImage = async () => {
let result = await ImagePicker.launchImageLibraryAsync({
mediaTypes: ImagePicker.MediaTypeOptions.Images,
allowsEditing: true,
aspect: [4,3],
quality:1,
});
console.log(result);
if (!result.cancelled){
setImage(result.uri);
}
};
if (hasGalleryPermission === false){
return <Text>No access to internal storage.</Text>
}
return (
<View style={styles.container}>
{image && <ImageBackground source={{uri: image}} style={styles.tankPhoto}/>}
<Button title="Add photo" color="lightgreen" onPress={() => pickImage()} />
<NavBar />
</View>
)
}
const styles = StyleSheet.create({
container: {
borderColor: '#C0C0C0',
borderWidth: 1,
backgroundColor: '#FFF',
borderRadius: 50,
width: 330,
flex: 1,
alignItems: 'center',
marginLeft: 'auto',
marginRight: 'auto',
margin: 30,
},
tankPhoto: {
flex: 1,
height: 150,
width: 200,
borderWidth: 1,
margin: 25,
},
})
export default AddPhoto;
What am I doing wrong, or is there a better way to do this? What I need:
let me include buttons in another file that would let me navigate to the screen in the nav.js file that I specified with the button.
React native navigation documentation: https://reactnavigation.org/docs/getting-started
Move these lines outside the NavBar component:
const Stack = createNativeStackNavigator();
{/* Homescreen */}
const HomeScreen = ( {navigation} ) => {
return (
<ScrollView style={homeStyle.container}>
<AddTank />
<Button title="Go to tasks" color="lightblue" onPress={() => navigation.navigate('Tasks')}/>
</ScrollView>
)
}
{/* Default config */}
const Config = ( {navigation } ) => {
return (
<View></View>
)
}
I ended up making this work. I defined
const navigation = useNavigation();
in my code (under AddPhoto constant) and imported:
import { useNavigation } from '#react-navigation/native'; in the same file (photo.js).

How to add tabs and show the name of the button in the header of the application?

How to add submenu or tabs in the upper part in connection with the lower button and show the name of the lower button in the header of the application.
import React from 'react';
import { createStackNavigator } from 'react-navigation-stack';
import { createBottomTabNavigator } from 'react-navigation-tabs';
import { createAppContainer } from 'react-navigation';
import { MaterialIcons, MaterialCommunityIcons } from '#expo/vector-icons';
import Splash from '../screens/Splash';
import NewsListScreen from '../screens/NewsListScreen';
import NewsItemScreen from '../screens/NewsItemScreen';
const StackNavigator = createStackNavigator({
//Splash: {screen: Splash},
News: {
screen: NewsListScreen
},
NewsItem: {
screen: NewsItemScreen,
navigationOptions: {
headerTitle: 'News Item'
}
}
});
const BottomTabNavigator = createBottomTabNavigator({
Home: {
screen: StackNavigator,
navigationOptions: {
tabBarIcon: () => <MaterialIcons name="home" size={24} />
}
},
News: {
screen: StackNavigator,
navigationOptions: {
tabBarIcon: () => <MaterialCommunityIcons name="newspaper-variant-outline" size={24} />
}
}
})
export default createAppContainer(BottomTabNavigator);
What I want to achieve is the following:
As you can see, the bottom button [News] has three referential buttons in the upper part [FEATURED], [RELEVANT], [SEARCH] and, in addition to that, it recovers the name of the bottom button and adds it to the application header below the top buttons.
[EDITED]
Your NewsListScreen screen, instead of just being a tab bar component, can be something like that:
function NewsListScreen = (props) => (
<View>
<Text>News</Text>
<TabBarComponent {...props} />
</View>
)
function TabBarComponent = createMaterialTopTabNavigator({
featured: ... ,
relevant: ... ,
search: ... ,
})
That being said, if you can, you should update your project to react navigation v5, which is I think much more user friendly.
Final Output:
Implementation using react-navigation v5 :
import * as React from 'react';
import { Text, View, StyleSheet, Dimensions } from 'react-native';
import Constants from 'expo-constants';
import {
NavigationContainer,
useNavigationState,
} from '#react-navigation/native';
import { createBottomTabNavigator } from '#react-navigation/bottom-tabs';
import { createMaterialTopTabNavigator } from '#react-navigation/material-top-tabs';
const TopTab = createMaterialTopTabNavigator();
const BottomTab = createBottomTabNavigator();
/*
Here I am using MaterialTopTabNavigator instead of StackNavigator,
which is a better choice based on UI snapshot in this case.
*/
function NewsTopTabs() {
/*
in case you want to set the title dynamically then you can use the
useNavigationState hook but as there are just two bottom tabs so
I am using hardcoded values.
*/
const nav = useNavigationState((state) => state);
return (
<>
<View style={styles.titleBar}>
<Text style={styles.title}>News</Text>
</View>
<TopTab.Navigator>
<TopTab.Screen name="Featured" component={Featured} />
<TopTab.Screen name="Relevant" component={Relevant} />
<TopTab.Screen name="Search" component={Search} />
</TopTab.Navigator>
</>
);
}
function MatchesTopTabs() {
return (
<>
<View style={styles.titleBar}>
<Text style={styles.title}>Matches</Text>
</View>
<TopTab.Navigator>
<TopTab.Screen name="Featured" component={Featured} />
<TopTab.Screen name="Relevant" component={Relevant} />
<TopTab.Screen name="Search" component={Search} />
</TopTab.Navigator>
</>
);
}
function MyBottomTabs({ navigation }) {
return (
<BottomTab.Navigator>
<BottomTab.Screen name="News" component={NewsTopTabs} />
<BottomTab.Screen name="Matches" component={MatchesTopTabs} />
</BottomTab.Navigator>
);
}
//[FEATURED], [RELEVANT], [SEARCH]
export default function App() {
return (
<NavigationContainer>
<MyBottomTabs />
</NavigationContainer>
);
}
//[FEATURED], [RELEVANT], [SEARCH]
const Featured = () => {
const nav = useNavigationState((state) => state);
return (
<View style={styles.screen}>
<Text>Featured</Text>
</View>
);
};
const Relevant = () => {
const nav = useNavigationState((state) => state);
return (
<View style={styles.screen}>
<Text>Relevant</Text>
</View>
);
};
const Search = () => {
const nav = useNavigationState((state) => state);
return (
<View style={styles.screen}>
<Text>Search</Text>
</View>
);
};
const styles = StyleSheet.create({
titleBar: {
height: 50,
width: Math.round(Dimensions.get('window').width),
backgroundColor: 'white',
justifyContent: 'center',
borderBottomColor: "lightgrey",
borderBottomWidth: 1,
paddingLeft: 10,
},
title: {
fontSize: 20,
fontWeight: 'bold',
},
screen:{
flex: 1,
justifyContent: "center",
alignItems: "center"
}
});
Working Example: Expo Snack

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.

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;