I need help importing drawer navigation into my App.js - react-native

All of my code is in my App.js file but drawer navigation doesn't seem to be working when I integrate it. The drawer navigation is in a different file and I imported it into my App.js. This is my code for the file:
import React from 'react';
import { NavigationContainer } from '#react-navigation/native';
import { createNativeStackNavigator } from '#react-navigation/native-stack';
import { StyleSheet, Text, View, Button, Image, TextInput, TouchableOpacity, FlatList, SafeAreaView, Dimensions, } from 'react-native';
import { StatusBar } from 'expo-status-bar';
import { Ionicons } from '#expo/vector-icons';
import {Octicons} from '#expo/vector-icons';
import {AntDesign} from '#expo/vector-icons';
import {MaterialIcons, MaterialCommunityIcons } from '#expo/vector-icons';
import { useState } from "react";
import ReactDOM from "react-dom/client";
import analytics from '#react-native-firebase/analytics';
import 'react-native-gesture-handler';
import {
createDrawerNavigator,
DrawerContentScrollView,
DrawerItemList,
DrawerItem,
} from '#react-navigation/drawer';
const Drawer = createDrawerNavigator();
const MyStack = () => {
return (
<NavigationContainer>
<Drawer.Navigator useLegacyImplementation initialRouteName="Home">
<Drawer.Screen name="Home" component={HomeScreen} />
<Drawer.Screen name="Login" component={LoginScreen} />
</Drawer.Navigator>
<Stack.Navigator>
<Stack.Screen
name="Home"
component={HomeScreen}
options={{
title: '',
headerLeft: () => (
<View style={{flexDirection:'row'}} >
<TouchableOpacity style={{left: 50, top: 45}}>
<Ionicons name="reorder-three" color="black" size={40} />
</TouchableOpacity>
<Image
style={{width: 50, height: 50 , left: 100, top: 40}}
source={require('./assets/videocamera.png')}
/>
<Image
style={{width: 140, height: 140, left: 90}}
source={require('./assets/vihubprofile.png')}
/>
</View>
),
headerRight: () => (
<View style={{flexDirection:'row'}} >
<TouchableOpacity style={styles.input}>
<TextInput style={styles.textinput} placeholder=" Search "></TextInput>
</TouchableOpacity>
<TouchableOpacity style={{right: 350, top: 5 }}>
<Ionicons name="ios-search" color="grey" size={30} />
</TouchableOpacity>
<TouchableOpacity style={{right: 50 }}>
<Ionicons name="settings" color="black" size={40} />
</TouchableOpacity>
<TouchableOpacity style={styles.signinheader} onPress={() => navigation.navigate('login')}>
<Text style={styles.signincolor}>SIGN IN</Text>
</TouchableOpacity>
<TouchableOpacity style={styles.signup} onPress={() => navigation.navigate('signup')}>
<Text style={styles.signupcolor}>SIGN UP</Text>
</TouchableOpacity>
</View>
),
}}
/>
<Stack.Screen name="login" component={LoginScreen} options={{ headerShown: false }} />
<Stack.Screen name="signup" component={SignupScreen} options={{ headerShown: false }} />
</Stack.Navigator>
</NavigationContainer>
);
}
The problem is in my navigation container because I think my stack navigator is already in there so there is an error.

Related

What is the proper way to have only one header with Open Drawer and Back button?

What I need is a single header with a back button on StackScreen2 and a toggle drawer button in StackScreen1.
I apologise for my poor writing and English.
import * as React from 'react';
import { Button, View, Text } from 'react-native';
import { createDrawerNavigator } from '#react-navigation/drawer';
import { NavigationContainer } from '#react-navigation/native';
import { createNativeStackNavigator } from '#react-navigation/native-stack';
const Stack = createNativeStackNavigator();
function StackScreen1({ navigation }) {
return (
<View>
<Text>StackScreen1</Text>
<Button title="Go To StackScreen2" onPress={() => navigation.navigate("StackScreen2")} />
</View>
)
}
function StackScreen2() {
return (
<View>
<Text>StackScreen2</Text>
</View>
)
}
function DrawerScreen1() {
return (
<Stack.Navigator>
<Stack.Screen name="StackScreen1" component={StackScreen1} />
<Stack.Screen name="StackScreen2" component={StackScreen2} />
</Stack.Navigator>
)
}
function DrawerScreen2() {
return (
<View>
<Text>DrawerScreen2</Text>
</View>
)
}
const Drawer = createDrawerNavigator();
export default function Test3() {
return (
<NavigationContainer>
<Drawer.Navigator>
<Drawer.Screen name="DrawerScreen1" component={DrawerScreen1} />
<Drawer.Screen name="DrawerScreen2" component={DrawerScreen2} />
</Drawer.Navigator>
</NavigationContainer>
);
}
StackScreen1
StackScreen2
I tried hiding drawer header but then I don't have toggle drawer button anywhere.
Check below code for drawer navigation:
import * as React from 'react';
import { Button, View } from 'react-native';
import { createDrawerNavigator } from '#react-navigation/drawer';
import { NavigationContainer } from '#react-navigation/native';
function HomeScreen({ navigation }) {
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Button
onPress={() => navigation.navigate('Notifications')}
title="Go to notifications"
/>
</View>
);
}
function NotificationsScreen({ navigation }) {
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Button onPress={() => navigation.goBack()} title="Go back home" />
</View>
);
}
const Drawer = createDrawerNavigator();
export default function App() {
return (
<NavigationContainer>
<Drawer.Navigator useLegacyImplementation initialRouteName="Home">
<Drawer.Screen name="Home" component={HomeScreen} />
<Drawer.Screen name="Notifications" component={NotificationsScreen} />
</Drawer.Navigator>
</NavigationContainer>
);
}
You can check more about drawer here.
May be this will help you!
import * as React from 'react';
import { Ionicons, FontAwesome } from '#expo/vector-icons';
import { Button, View, Text, Pressable,Image } from 'react-native';
import { NavigationContainer } from '#react-navigation/native';
import { createNativeStackNavigator } from '#react-navigation/native-stack';
import { createBottomTabNavigator } from '#react-navigation/bottom-tabs';
import { createDrawerNavigator } from '#react-navigation/drawer';
function HomeScreen({ navigation }) {
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Text>Home Screen</Text>
<Button
title="Go to Details"
onPress={() => navigation.navigate('SettingsScreen')}
/>
</View>
);
}
function DetailsScreen() {
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Text>Details Screen</Text>
<Button
title="Go to Details"
onPress={() => navigation.goBack()}
/>
</View>
);
}
const Drawer = createDrawerNavigator();
function MyDrawer() {
return (
<Drawer.Navigator
useLegacyImplementation
// screenOptions={{
// drawerLabelStyle: { fontSize: 17, color: '#000',marginLeft:-30 }
// }}
>
<Drawer.Screen
name="HomeScreen"
component={DetailsScreen}
screenOptions={{
headerShown: false,
}}
/>
</Drawer.Navigator>
);
}
function MyTabs() {
return (
<Tab.Navigator>
<Tab.Screen
name="SettingsScreen"
component={MyDrawer}
options={{
headerShown: false,
tabBarIcon: ({ color, size }) => (
<Ionicons name="md-home" size={24} color={'#eee'} />
),
tabBarStyle: { position: 'absolute' },
tabBarActiveTintColor: '#eee',
tabBarInactiveTintColor: '#eee',
}}
/>
<Tab.Screen
name="DetailsScreen"
component={DetailsScreen}
options={{
headerShown: false,
tabBarIcon: ({ color, size }) => (
<Image source={{uri:"https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcTUAN0zLcvLFjdaYN1dBRSKoIuJndRW6VuX85w2yzEzxvTwO3B0Y_gv1x8kVDISNKJEbq0&usqp=CAU"}}
style={{width:24,height:24,borderRadius:24}} />
),
tabBarStyle: { position: 'absolute' },
tabBarActiveTintColor: '#eee',
tabBarInactiveTintColor: '#eee',
}}
/>
</Tab.Navigator>
);
}
function SettingsScreen() {
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Text>2</Text>
</View>
);
}
const Stack = createNativeStackNavigator();
const Tab = createBottomTabNavigator();
function App() {
return (
<NavigationContainer>
<Stack.Navigator initialRouteName="HomeScreen">
<Stack.Screen
name="HomeScreen"
component={HomeScreen}
options={{ headerShown: false }}
/>
<Stack.Screen
name="SettingsScreen"
component={MyTabs}
options={{ headerShown: false }}
/>
</Stack.Navigator>
</NavigationContainer>
);
}
export default App;

Why my panel is hiding the body of my views?

i want to build a built a navigation with BottomTabNavigator but i dont know what happen i never see the body of my screens, something is hidding the body, i created a demo to demostrate you the wrong, but its too simple.
this is the file App.js
import React from 'react'
//import { Provider } from 'react-native-paper'
import { Provider, useSelector } from 'react-redux'
import { createStore } from 'redux'
import { NavigationContainer } from '#react-navigation/native'
import { View, Text } from 'react-native'
import { createStackNavigator } from '#react-navigation/stack'
import { createBottomTabNavigator } from '#react-navigation/bottom-tabs'
const Stack = createStackNavigator()
function HomeScreen() {
return (
<View
style={{
flexDirection: 'row',
height: 100,
padding: 20,
}}
>
<View style={{ backgroundColor: 'blue', flex: 0.3 }} />
<View style={{ backgroundColor: 'red', flex: 0.5 }} />
<Text>Hello World!</Text>
</View>
)
}
function SettingsScreen() {
return (
<View
style={{
backgroundColor: 'red',
flex: 1,
color: 'green',
justifyContent: 'center',
alignItems: 'center',
}}
>
<Text>Settings!</Text>
</View>
)
}
const Tab = createBottomTabNavigator()
function MyTabs() {
return (
<Tab.Navigator>
<Tab.Screen name="Home" component={HomeScreen} />
<Tab.Screen name="Settings" component={SettingsScreen} />
</Tab.Navigator>
);
}
export default function App() {
return (
<NavigationContainer>
<Stack.Navigator initialRouteName="main">
<Stack.Screen name="loginScreen" component={SettingsScreen} />
<Stack.Screen name="main" component={MyTabs} />
</Stack.Navigator>
</NavigationContainer>
)
}
i am trying to do, before to user is logged i would like to hidde the tabs
something is hidding
edit 1: why i have 2 headers?
On the web, #react-navigation/bottom-tabs mistakenly treat screens in the tab as inactive and detaches them.
The solution is to disable detach inactive screens for bottom tab.
import React from "react";
//import { Provider } from 'react-native-paper'
import { Provider, useSelector } from "react-redux";
import { createStore } from "redux";
import { NavigationContainer } from "#react-navigation/native";
import { View, Text } from "react-native";
import { createStackNavigator } from "#react-navigation/stack";
import { createBottomTabNavigator } from "#react-navigation/bottom-tabs";
const Stack = createStackNavigator();
function HomeScreen() {
return (
<View
style={{
flexDirection: "row",
height: 100,
padding: 20,
}}
>
<View style={{ backgroundColor: "blue", flex: 0.3 }} />
<View style={{ backgroundColor: "red", flex: 0.5 }} />
<Text>Hello World!</Text>
</View>
);
}
function SettingsScreen() {
return (
<View
style={{
backgroundColor: "red",
flex: 1,
color: "green",
justifyContent: "center",
alignItems: "center",
}}
>
<Text>Settings!</Text>
</View>
);
}
const Tab = createBottomTabNavigator();
function MyTabs() {
return (
<Tab.Navigator detachInactiveScreens={false}>
<Tab.Screen name="Home" component={HomeScreen} options={{headerShown:false}} />
<Tab.Screen name="Settings" component={SettingsScreen} options={{headerShown:false}}/>
</Tab.Navigator>
);
}
export default function App() {
return (
<NavigationContainer>
<Stack.Navigator initialRouteName="main" >
<Stack.Screen name="loginScreen" component={SettingsScreen} options={{headerShown:false}}/>
<Stack.Screen name="main" component={MyTabs} options={{headerShown:false}} />
</Stack.Navigator>
</NavigationContainer>
);
}
Moving between screens
You can create a state for handling user logged in status or you can also use redux for it so It will automatically navigate to the main screen after user logged in
export default function App() {
return (
<NavigationContainer>
<Stack.Navigator>
{state.userToken == null ? (
// No token found, user isn't signed in
<Stack.Screen name="loginScreen" component={LoginScreen} />
) : (
// User is signed in
<Stack.Screen name="main" component={MyTabs} />
)}
</Stack.Navigator>
</NavigationContainer>
);
}
More details Here

How can I place an icon before Home and Notifications of the Drawer.Screen

I am learning how to use React Navigation.
How can I place an icon before Home and Notifications of the Drawer.Screen
import * as React from 'react';
import { Button, View } from 'react-native';
import { createDrawerNavigator } from '#react-navigation/drawer';
import { NavigationContainer } from '#react-navigation/native';
function HomeScreen({ navigation }) {
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Button
onPress={() => navigation.navigate('Notifications')}
title="Go to notifications"
/>
</View>
);
}
function NotificationsScreen({ navigation }) {
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Button onPress={() => navigation.goBack()} title="Go back home" />
</View>
);
}
const Drawer = createDrawerNavigator();
export default function App() {
return (
<NavigationContainer>
<Drawer.Navigator initialRouteName="Home">
<Drawer.Screen name="Home" component={HomeScreen} />
<Drawer.Screen name="Notifications" component={NotificationsScreen} />
</Drawer.Navigator>
</NavigationContainer>
);
}
And how do I do so that when entering the view add a tab screen
You can create a custom component and render it in your drawer.
Here the ButtonList is a custom component that you pass it to drawerContent. And you can create a list in the ButtonList and put the icon between Home and Notification easily.
<ActionDrawer.Navigator
drawerType="back"
drawerPosition="right"
drawerContent={(props) => <ButtonList {...props} />}
drawerStyle={{
width: wp('65'),
}}
>

ReactNative how to disable click on drawer menu item

the drawer menu setup is like below.
how can i disable click on first Drawer.Screen ?
it must show a single image!!
also how can i hide one element programmatically?
<Drawer.Navigator
initialRouteName="Feed"
drawerPosition="right"
drawerStyle={{
backgroundColor: '#c7c4b8',
width: 240,
}}
overlayColor="transparent">
<Drawer.Screen
name="Profile2"
component={Profile2}
options={{ drawerLabel: '', drawerIcon: ({ focused, size }) => (
<Image source={require('./images/3.jpg')} resizeMode={'cover'} style={{ width: '100%', height: 200 }} />)
}}
/>
<Drawer.Screen
name="Home"
component={Notifications}
options={{ drawerLabel: 'Feed' }}
/>
<Drawer.Screen
name="Routes"
component={Profile}
options={{ drawerLabel: 'Routes' }}
/>
</Drawer.Navigator>
For add header or whatever you want you should use drawerContent prop and there you can make your custom drawer or manipulate the existing one like in the example below.
For show/hide screen in a drawer programatically you can just use it with useState or pass a redux store and conditionally render it or not, remember that navigator its just a react component.
I let you a snack to check it online as well.
https://snack.expo.io/#anthowm/drawer-navigation-%7C-react-navigation
import * as React from 'react';
import {useState} from 'react';
import { View, Text, Image } from 'react-native';
import { NavigationContainer } from '#react-navigation/native';
import {
createDrawerNavigator,
DrawerContentScrollView,
DrawerItemList,
DrawerItem,
} from '#react-navigation/drawer';
function Feed() {
return (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<Text>Feed Screen</Text>
</View>
);
}
function Article() {
return (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<Text>Article Screen</Text>
</View>
);
}
function CustomDrawerContent(props) {
return (
<DrawerContentScrollView {...props}>
<Image source={{
uri: 'https://reactnative.dev/img/tiny_logo.png',
}} resizeMode={'cover'} style={{ width: '100%', height: 200 }} />
<DrawerItemList {...props} />
<DrawerItem
label="Hide Screen"
onPress={() => props.setShow(false)}
/>
</DrawerContentScrollView>
);
}
const Drawer = createDrawerNavigator();
function MyDrawer() {
const [show, setShow] = useState(true);
return (
<Drawer.Navigator drawerContent={props => <CustomDrawerContent setShow={setShow} {...props} />}>
<Drawer.Screen name="Feed" component={Feed} />
{show && <Drawer.Screen name="Article" component={Article} />}
</Drawer.Navigator>
);
}
export default function App() {
return (
<NavigationContainer>
<MyDrawer />
</NavigationContainer>
);
}

TouchableOpacity onpress is not working with Navigation

I am using react native Navigation and I put a switch inside the header to toggle between light and dark theme while using touchableOpacity onPress prop. No error logs, and when I press the switch, the touchableOpacity onpress is not firing up. I did share my App.js code, I would appreciate if you can see and point where I am doing wrong.
/**
* Sample React Native App
* https://github.com/facebook/react-native
*
* #format
* #flow strict-local
*/
import React, {useState} from 'react';
import {StatusBar, View, TouchableOpacity} from 'react-native';
import {NavigationContainer} from '#react-navigation/native';
import Home from './src/screens/Home';
import Details from './src/screens/Details';
import {createStackNavigator} from '#react-navigation/stack';
import {DarkTheme, Text, Title, TouchableRipple, Switch} from 'react-native-paper';
import MaterialCommunityIcons from 'react-native-vector-icons/MaterialCommunityIcons';
const Stack = createStackNavigator();
const App = () => {
const [isDartheme, setDarkTheme] = useState(false);
const togglemethod = () => {
console.log("Called!");
setDarkTheme(!isDartheme);
};
return (
<>
<NavigationContainer>
<StatusBar barStyle="dark-content" />
<Stack.Navigator screenOptions={{headerTitleAlign: 'center'}}>
<Stack.Screen
name="Home"
component={Home}
options={{
headerTitle: (props) => (
<View style={{ flexDirection: 'row'}}>
<View>
<Title style={{paddingLeft: 130}}>
<Text>Home</Text>
</Title>
</View>
<View >
<TouchableOpacity
onPress={ () => {togglemethod() }
}
centered ={true}
>
<MaterialCommunityIcons
name={isDartheme?'moon-waning-crescent': 'white-balance-sunny'}
size = {25}
color= "blue"
style={{paddingLeft: 110, paddingBottom:5, width: '200%'}}
>
<Switch
value={isDartheme}
color="red"
style={{paddingLeft: 8}}
/>
</MaterialCommunityIcons>
</TouchableOpacity>
</View>
</View>
),
}}
/>
</Stack.Navigator>
</NavigationContainer>
</>
);
};
export default App;
There is a typo on the method that you are calling change the onPress from togglemlethod to togglemethod
Here is the working version of the code,
You should not place the Switch inside the icon which results in an error
You can use the switch itself to trigger the toggle,
You will have to change the styles according to your need, but this works fine on android.
<Stack.Navigator screenOptions={{ headerTitleAlign: 'center' }}>
<Stack.Screen
name="Home"
component={HomeScreen}
options={{
headerTitle: (props) => (
<View style={{ flexDirection: 'row' }}>
<View>
<Title style={{ paddingLeft: 130 }}>
<Text>Home</Text>
</Title>
</View>
<View>
<TouchableOpacity
onPress={() => {
togglemethod();
}}
centered={true}
style={{ flexDirection: 'row',alignItems:'center' }}>
<Switch
value={isDartheme}
color="red"
onValueChange={() => togglemethod()}
/>
<MaterialCommunityIcons
name={
isDartheme
? 'moon-waning-crescent'
: 'white-balance-sunny'
}
size={25}
color="blue"
style={{
paddingBottom: 5,
}}></MaterialCommunityIcons>
</TouchableOpacity>
</View>
</View>
),
}}
/>
</Stack.Navigator>