React Native drawer navigation screen header title and buttons - react-native

I am trying to add title and buttons to my home screen that is opened from drawer navigation. The following does not work(screen loads but no header) and i cant find documentation or sample on this that uses React Navigation v5. Did i miss something? This is the doc i am following.
<Drawer.Screen
name="Home"
component={HomeScreen}
title="Home Screen"
options={{
headerRight: () => (
<Button
onPress={() => alert("This is a button!")}
title="Info"
color="#fff"
/>
),
}}
/>
UPDATE: doing this on the screen didn't work as well.
const HomeScreen = (props) => {
return (
<Container>
<View style={{ flex: 1, alignItems: "center", justifyContent: "center" }}>
<Text>Home Screen2</Text>
</View>
</Container>
);
};
HomeScreen.navigationOptions = (props) => ({
title: "Home",
headerStyle: {
backgroundColor: "rgb(0, 145, 234)",
},
headerTintColor: "white",
headerTitleStyle: {
fontWeight: "bold",
color: "white",
},
});
export default HomeScreen;

From the option you put in, I guess you may want to add a Stack inside your Drawer navigation.
From the below example, when you go to the HomeStack, it will have a navigation bar and you can custom it using the option you put in.
(I also created a simple snack here: https://snack.expo.io/#gie3d/insane-ice-cream)
import React from 'react';
import { Text, View } from 'react-native';
import { NavigationContainer, DrawerActions } from '#react-navigation/native';
import { createStackNavigator } from '#react-navigation/stack';
import { createDrawerNavigator } from '#react-navigation/drawer';
import { Ionicons } from '#expo/vector-icons';
const Stack = createStackNavigator();
const Drawer = createDrawerNavigator();
const HomeStack = () => (
<Stack.Navigator>
<Stack.Screen name="Home" component={Home} options={({navigation}) => ({
title: "Home",
headerStyle: {
backgroundColor: "rgb(0, 145, 234)",
},
headerTintColor: "white",
headerTitleStyle: {
fontWeight: "bold",
color: "white",
},
headerLeft: () => (
<Ionicons
name={'md-menu'}
size={24}
style={{ marginLeft: 10 }}
onPress={() =>
navigation.dispatch(DrawerActions.toggleDrawer())
}
/>
),
})} />
</Stack.Navigator>
);
const Home = () => {
return (
<View>
<Text>This is Home</Text>
</View>
)}
export default () => {
return (
<NavigationContainer>
<Drawer.Navigator initialRouteName="HomeStack">
<Drawer.Screen name="HomeStack" component={HomeStack} />
<Drawer.Screen name="HomeNoStack" component={Home} />
</Drawer.Navigator>
</NavigationContainer>
);
}

You need to create the button on your screen too, like this.
import React from "react";
import {Text, View} from 'react-native';
export default class News extends React.Component {
static navigationOptions = ({navigation}) => {
return {
//headerLeft: --- PUT HERE YOU CUSTOM BUTTON (Use navigation.goBack() in onPress)
headerLeft:(<HeaderBackButton size={20} onPress={()=>{navigation.navigate('Home')}} color="#fff" tintColor="#fff"/>),
headerStyle: {
backgroundColor: 'rgb(0, 145, 234)',
},
headerTintColor: 'white',
headerTitleStyle:
{
fontWeight: 'bold',
color:'white' ,
//paddingTop:"2%",
},
}
}
render() {
return (
<View>
<Text> Here Leave the News!! </Text>
</View>
);
}
}

Related

react native why my navigation shows me 2 headers?

I want to custom my header. The Problem is, it shows me two headers. My custom header and the Tab Header "Home".
import * as React from 'react';
import { StyleSheet, Text, View, TouchableOpacity, Image } from 'react-native';
import { NavigationContainer } from '#react-navigation/native';
import { createNativeStackNavigator } from '#react-navigation/native-stack';
import {
BottomTabBar,
createBottomTabNavigator,
} from '#react-navigation/bottom-tabs';
import { Entypo, FontAwesome5 } from '#expo/vector-icons';
import Home from '../screens/Home';
import News from '../screens/News';
import Weapons from '../screens/stack/Weapons';
import HeaderHome from '../shared/headerHome';
const Stack = createNativeStackNavigator();
const Tab = createBottomTabNavigator();
const TabBar = () => (
<Tab.Navigator
tabBar={(props) => {
return (
<View>
<BottomTabBar {...props} />
</View>
);
}}
screenOptions={{
tabBarStyle: [{ display: 'flex' }],
tabBarShowLabel: true,
tabBarLabelStyle: {
paddingBottom: 6,
color: '#333',
},
}}>
<Tab.Screen
name="Home"
component={Home}
options={{
tabBarIcon: ({ color, focused }) => (
<Entypo name="home" size={24} color={focused ? '#37bfff' : '#888'} />
),
}}
/>
<Tab.Screen
name="News"
component={News}
options={{
tabBarIcon: ({ color, focused }) => (
<Entypo
name="newsletter"
size={24}
color={focused ? '#37bfff' : '#888'}
/>
),
}}
/>
</Tab.Navigator>
);
const Navigation = () => (
<NavigationContainer>
<Stack.Navigator>
<Stack.Screen
name="HomeScreen"
component={TabBar}
options={{
header: () => <HeaderHome />,
}}
/>
</Stack.Navigator>
</NavigationContainer>
);
const styles = StyleSheet.create({
navigator: {
borderTopWidth: 0,
backgroundColor: 'transparent',
elevation: 30,
height: 60,
},
});
export default Navigation;
You can add a option to hide the Tab.Navigator's header. Add headerShown: false to the screenOptions of Tab.Navigator as shown below
<Tab.Navigator
tabBar={(props) => {
return (
<View>
<BottomTabBar {...props} />
</View>
);
}}
screenOptions={{
tabBarStyle: [{ display: 'flex' }],
tabBarShowLabel: true,
tabBarLabelStyle: {
paddingBottom: 6,
color: '#333',
},
headerShown: false, // <--- Here
}}>
Check out the working example for your scenario here
On the other hand, if you want to hide the Stack.Navigator's header, you can do as shown below
<Stack.Navigator screenOptions={{ headerShown: false }}>

Add openDrawer() to hamburger menu on a header in React Native -gives error undefined

This is my first React Native app. I want to get the header hamburger icon to open the side bar (drawer) but it only read it as undefined. So I read that it´s not possible to implement openDrawer() on a header as it is not read as a "screen". I have not been able to understand how to change my code to make it work. Help appreciated.
My code:
//Header
import React from "react";
import { StyleSheet, View, Text, TouchableOpacity } from "react-native";
import { Ionicons } from "#expo/vector-icons";
export const Header = ({ navigation, title }) => {
const openMenu = () => {
navigation.openDrawer();
};
return (
<View style={styles.header}>
<TouchableOpacity onPress={openMenu} style={styles.icons}>
<Ionicons name="md-menu" size={28} color="white" />
</TouchableOpacity>
<View style={styles.headerTitle}>
<Text style={styles.headerText}>{title}Title for header</Text>
</View>
</View>
);
};
//Navigation screen
import React from "react";
import { NavigationContainer } from "#react-navigation/native";
import { createDrawerNavigator } from "#react-navigation/drawer";
import { Notifications } from "./screens/Notifications";
import { Profile } from "./screens/Profile";
import { Header } from "./screens/Header";
const Drawer = createDrawerNavigator();
export const Navigation = () => {
return (
<>
<Header />
<NavigationContainer>
<Drawer.Navigator>
<Drawer.Screen name="Login" component={Login} />
<Drawer.Screen name="Profile" component={Profile} />
<Drawer.Screen name="Notifications" component={Notifications} />
</Drawer.Navigator>
</NavigationContainer>
</>
);
};
Firstly, create a folder called navigation where your App.js is located
Inside navigation folder create a file called AppNavigator.js
Then paste this inside AppNavigator.js
import React from "react";
import { createDrawerNavigator } from "#react-navigation/drawer";
import { Notifications } from "./screens/Notifications";
import { Profile } from "./screens/Profile";
const Drawer = createDrawerNavigator();
function AppNavigator() {
return (
<Drawer.Navigator screenOptions={{ headerShown: true }}>
<Drawer.Screen name="Profile" component={Profile} />
<Drawer.Screen name="Notifications" component={Notifications} />
</Drawer.Navigator>
);
}
export default AppNavigator;
In your App.js paste this code
import React from "react";
import { NavigationContainer } from "#react-navigation/native";
import AppNavigator from "./navigation/AppNavigator"
const App = () => {
return (
<NavigationContainer>
<AppNavigator />
</NavigationContainer>
);
};
export default App;
Your Login.js would look like this
import React, { useState } from "react";
import {
TouchableOpacity,
TextInput,
Text,
View,
StyleSheet,
} from "react-native";
export const Login = ({ navigation }) => {
const [userName, setUserName] = useState("");
const [password, setPassword] = useState("");
return (
<View style={styles.container}>
<Text style={styles.welcomeText}>Welcome to your App</Text>
<View style={styles.inputView}>
<TextInput
// required
style={styles.inputText}
placeholder="Email"
placeholderTextColor="#fff"
onChangeText={(value) => setUserName(value)}
defaultValue={userName}
/>
</View>
<View style={styles.inputView}>
<TextInput
// required
style={styles.inputText}
placeholder="Password"
placeholderTextColor="#fff"
onChangeText={(value) => setPassword(value)}
defaultValue={password}
/>
</View>
<TouchableOpacity>
<Text style={styles.forgot}>Forgot Password?</Text>
</TouchableOpacity>
<TouchableOpacity
style={styles.loginButton}
title="Login"
onPress={() => navigation.navigate("NavigationTest", { userName })}
>
<Text style={styles.loginText}>LOGIN</Text>
</TouchableOpacity>
</View>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
alignItems: "center",
justifyContent: "center",
},
welcomeText: {
color: "#fb5b5a",
fontWeight: "bold",
fontSize: 50,
textAlign: "center",
margin: 40,
},
inputView: {
width: "80%",
backgroundColor: "#465880",
borderRadius: 25,
height: 50,
marginBottom: 20,
justifyContent: "center",
padding: 20,
},
inputText: {
height: 50,
color: "white",
},
loginButton: {
width: "80%",
backgroundColor: "#fb5b5a",
borderRadius: 25,
height: 50,
alignItems: "center",
justifyContent: "center",
marginTop: 40,
marginBottom: 10,
},
forgot: {
color: "grey",
},
loginText: {
color: "#ffff",
fontWeight: "bold",
},
});

React native navigation 5 stackNavigator not working on production

I'm using ReactNavigation for tab navigator and stackNavigator. It's working 100% on development, mode but the stacNavigator is not working on production builds. The app is not crashing, it just isn’t navigating through pages. But the tab navigator is working fine.
Anyone having this issue?
I have opened an issue.
App.js
import React from 'react';
import { StyleSheet, Text, View } from 'react-native';
import AdminHome from './AdminScr/AdminHome
import AdmLogin from './AdminScr/AdminLogin';
import { NavigationContainer } from '#react-navigation/native';
import { createStackNavigator } from '#react-navigation/stack';
function App() {
return (
<View style={styles.container} >
<Stack.Navigator style={{ backgroundColor: '#e91e63' }}>
<Stack.Screen name="AdmHome" component={AdminHome} options={{
title: 'Admin Home',
headerStyle: {
//backgroundColor: '#1e90ff',
backgroundColor: '#E66E2F'
},
headerTintColor: '#fff',
headerTitleStyle: {
fontWeight: 'bold',
},
}}
/>
<Stack.Screen name="AdmLogin" component={AdmLogin} options={{
title: 'Admin Login',
headerStyle: {
backgroundColor: '#E66E2F',
},
headerTintColor: '#fff',
headerTitleStyle: {
fontWeight: 'bold',
},
}}
/>
</Stack.Navigator>
</View>
);
}
export default () => {
return (
<NavigationContainer>
<App />
</NavigationContainer>
)
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#e91e63',
},
});
Calling in AdminLogin.js page.
//For Arrow Function
const AdmLogin=(props)=> { //Passing props in fat area like (props).
return (
<View>
<TouchableOpacity style={styles.signinbutton} onPress={() => props.navigation.navigate("AdmHome")} >
<Text style={styles.buttonText}> Sign In</Text>
</TouchableOpacity>
</View>
)}
//For Class Method
<TouchableOpacity style={styles.signinbutton} onPress={() => this.props.navigation.navigate("AdmHome")} >
<Text style={styles.buttonText}> Sign In</Text>
</TouchableOpacity>

React Native navigation v5 navigate to another screen from header

I am currently following a tutorial that has an older version of navigator. I have update the code to use v5. When moving to a screen the navigation function is available as in
const CreateScreen = ({ navigation }) => {
I am then able to set the navigation with
onPress={() => navigation.navigate("home")
Please can someone show me how to expose the navigation function within the createStackNavigator function
import React from 'react';
import { Text, TouchableOpacity } from 'react-native';
import { NavigationContainer } from '#react-navigation/native';
import { createStackNavigator } from '#react-navigation/stack';
import IndexScreen from "./src/screens/IndexScreens"
import ShowScreen from "./src/screens/ShowScreen"
import CreateScreen from "./src/screens/CreateScreen"
import EditScreen from "./src/screens/EditScreen"
import { Provider} from "./src/context/BlogContext"
import { Feather } from '#expo/vector-icons';
import { EvilIcons } from '#expo/vector-icons';
const Stack = createStackNavigator();
const MyStack = () => (
<Stack.Navigator>
<Stack.Screen
name="Home"
component={IndexScreen}
options={{
title: 'Blog Posts',
headerTitleStyle: {
fontWeight: 'bold',
},
headerTitleAlign: "center",
headerRight: () => (
<TouchableOpacity style={{ marginRight: 15}} onPress={() => alert('Not working need to pass navigation function')}>
<Feather name="plus" size={30} />
</TouchableOpacity>
)
}}
/>
<Stack.Screen
name="Show"
component={ShowScreen}
options={{
title: 'Blog Post Detail',
headerTitleStyle: {
fontWeight: 'bold',
},
headerTitleAlign: "center",
headerRight: () => (
<TouchableOpacity style={{ marginRight: 15}} onPress={() => alert('Not working need to pass navigation function')}>
<EvilIcons name="pencil" size={35} />
</TouchableOpacity>
)
}}
/>
<Stack.Screen
name="Create"
component={CreateScreen}
options={{
title: 'Create A Blog Post',
headerTitleStyle: {
fontWeight: 'bold',
},
headerTitleAlign: "center"
}}
/>
<Stack.Screen
name="Edit"
component={EditScreen}
options={{
title: 'Edit Blog Post',
headerTitleStyle: {
fontWeight: 'bold',
},
headerTitleAlign: "center"
}}
/>
</Stack.Navigator>
);
const App = () => (
<NavigationContainer>
<MyStack />
</NavigationContainer>
);
export default () => {
return <Provider>
<App />
</Provider>
}
change your options
options={{
title: 'Blog Posts',
headerTitleStyle: {
fontWeight: 'bold',
},
headerTitleAlign: "center",
headerRight: () => (
<TouchableOpacity style={{ marginRight: 15}} onPress={() => alert('Not working need to pass navigation function')}>
<Feather name="plus" size={30} />
</TouchableOpacity>
)
}}
to
options={({ navigation }) => (
{
title: 'Blog Posts',
headerTitleStyle: {
fontWeight: 'bold',
},
headerTitleAlign: "center",
headerRight: () => (
<TouchableOpacity style={{ marginRight: 15}} onPress={() => navigation.navigate("Show")}>
<Feather name="plus" size={30} />
</TouchableOpacity>
)
})}
Do the same with the options in Show stack screen.
Hope this helps!
Replace navigation.navigate("Show") with navigation.navigate("Create")

React Native, fixed header and footer for entire app with Navigation Drawer

I need to create a React native app with Navigation Drawer, and i'm facing some problems.
I have 3 different screen:
"HomeScreen", "ScreenOne", "ScreenTwo", "ScreenThree" and this is how my code for navigators:
export const HomeNavigator = createStackNavigator({
Home : { screen : HomeScreen },
One: { screen : ScreenOne},
Two : { screen : ScreenTwo }
},{
unmountInactiveRoutes : true,
headerMode: 'none'
});
the above navigator is specific for HomeScreen, where user can navigate to screenOne or screenTwo by tapping some element inside it.
The navigator below is for entire app:
export const AppDrawerNavigator = createDrawerNavigator({
HomePage : {
screen:HomeNavigator,
navigationOptions: {
drawerLabel: 'Homepage',
drawerIcon : ({tintColor}) =>(
<Icon name="home" color={tintColor}/>
)
}
},
One: {
screen:ScreenOne,
navigationOptions: {
drawerLabel: 'One'
}
},
Two: {
screen:ScreenTwo,
navigationOptions: {
drawerLabel: 'Two'
}
},
Three: {
screen:ScreenThree,
navigationOptions: {
drawerLabel: 'Three'
}
},{
initialRouteName: 'HomePage',
unmountInactiveRoutes : true,
headerMode: 'none'
}
});
Now i need to put a Fixed header and footer for entire app (the drawer must overlay header and footer when is opened),
where header must show an Hamburger menu button inside HomePage, and a BackButton near Hamburger inside the other screen (the footer remain the same all over the app).
How can i do?
You can configure your header with react navigation using navigationOptions property.
Add navigationOptions inside your stack navigator,then all your screens inside the stack navigator should contain a fixed header.
Example:
{
navigationOptions: ({ navigation }) => ({
headerRight: (
<View>
<TouchableOpacity
onPress={() => navigation.openDrawer()}
>
<Image source={hamburgerIcon} style={{ height: 15, width: 15 }} />
</TouchableOpacity>
</View>
),
headerTintColor: 'color',
headerTitle: (
<Text>
title
</Text>
),
headerStyle: {
backgroundColor: '#fff',
},
}),
});
For fixed footer you can use Tab navigation.
Example:
const TabNavigator = createBottomTabNavigator({
Home: { screen: HomeScreen },
Settings: { screen: SettingsScreen },
Gallery: { screen: Gallery}
});
Just add the header and footer in your App.js file or in your NavigationContainer above and below your navigator like in this snack or the following example.
import * as React from 'react';
import { View, Button, Text, Dimensions, StatusBar } from 'react-native';
import { NavigationContainer } from '#react-navigation/native';
import { createNativeStackNavigator } from '#react-navigation/native-stack';
function HomeScreen({ navigation }) {
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Text>Home Screen</Text>
<Button
title="Go to One"
onPress={() => navigation.navigate('One')}
/>
<Button
title="Go to Two"
onPress={() => navigation.navigate('Two')}
/>
</View>
);
}
function OneScreen({ navigation }) {
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Text>One Screen</Text>
<Button
title="Go to Home"
onPress={() => navigation.navigate('Home')}
/>
<Button
title="Go to Two"
onPress={() => navigation.navigate('Two')}
/>
</View>
);
}
function TwoScreen({ navigation }) {
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Text>Two Screen</Text>
<Button
title="Go to One"
onPress={() => navigation.navigate('One')}
/>
<Button
title="Go to Home"
onPress={() => navigation.navigate('Home')}
/>
</View>
);
}
const Stack = createNativeStackNavigator();
function App() {
const width = Dimensions.get('window').width;
return (
<NavigationContainer>
<StatusBar />
<View
style={{
backgroundColor: '#007AFF',
height: 50,
width: width,
justifyContent: 'center',
alignItems: 'center',
marginTop: StatusBar.currentHeight,
}}>
<Text>Header</Text>
</View>
<Stack.Navigator>
<Stack.Screen name="Home" component={HomeScreen} />
<Stack.Screen name="One" component={OneScreen} />
<Stack.Screen name="Two" component={TwoScreen} />
</Stack.Navigator>
<View
style={{
backgroundColor: '#007AFF',
height: 50,
width: width,
justifyContent: 'center',
alignItems: 'center',
}}>
<Text>Footer</Text>
</View>
</NavigationContainer>
);
}
export default App;