I am trying to build an demo app same like diagram below :
When, i am trying to navigate from Child screen to another screen , then drawer opens automatically :
Code: :
import React from 'react';
import { NavigationContainer } from '#react-navigation/native';
import { createStackNavigator, HeaderTitle } from '#react-navigation/stack';
import { createBottomTabNavigator } from '#react-navigation/bottom-tabs';
import { createDrawerNavigator } from '#react-navigation/drawer'
import FoodListScreen from '../screens/FoodListScreen';
import FoodDetailsScreen from '../screens/FoodDetailsScreen';
import FavouriteScreen from '../screens/FavouritesScreen';
import HomeScreen from '../screens/HomeScreen';
import AboutScreen from '../screens/AboutScreen';
import { Button, Text, View } from 'react-native';
const Stack = createStackNavigator();
const FavouriteStack = createStackNavigator();
const Drawer = createDrawerNavigator();
const Tab = createBottomTabNavigator();
//// ********** HOME TAB STACK View ************
function HomeStackScreens() {
return (
<Stack.Navigator initialRouteName="HomeScreen" screenOptions = {({route, navigation}) => (
{
title: 'My home',
mode:'card',
headerStyle: {
backgroundColor: '#f4511e',
},
headerTintColor: '#fff',
headerTitleStyle: {
fontWeight: 'bold',
},
headerRight: () => (
<HeaderTitle>
<Button
onPress={() => {
navigation.navigate('FoodDetailsScreen')
console.log('This is a Right !!')
}
}
title="Info!"
/>
<Button
onPress={() => console.log('This is a Right most button!')}
title="Edit"
/>
<Button
onPress={() => console.log('This is a Right most button!')}
title="Delete"
/>
</HeaderTitle>
),
})}>
<Stack.Screen name="HomeScreen" component={HomeScreen} />
<Stack.Screen name="FoodListScreen" component={FoodListScreen} />
<Stack.Screen name="FoodDetailsScreen" component={FoodDetailsScreen} options = {{
title: 'Food Details Title',
headerStyle: {
backgroundColor: '#000',
},
headerTintColor: '#fff',
}}/>
<Stack.Screen name="FavouriteList" component={FavouriteScreen} />
</Stack.Navigator>
);
}
//// ********** Favourite TAB STACK View ************
function FavouriteStackScreens() {
return (
<FavouriteStack.Navigator>
<FavouriteStack.Screen name="FavouriteScreen" component={FavouriteScreen} />
<FavouriteStack.Screen name="FoodDetailsScreen" component={FoodDetailsScreen} />
</FavouriteStack.Navigator>
);
}
/// **** TAB View Of HOME Item of Drawer ********
function HomePageTabScreen() {
return (
<Tab.Navigator>
<Tab.Screen name="FoodTab" component={HomeStackScreens} />
<Tab.Screen name="FavouriteTab" component={FavouriteStackScreens} />
</Tab.Navigator>
)
}
///// The Main Drawer
const AppNavigator = () => {
return (
<NavigationContainer>
<Drawer.Navigator initialRouteName="NavHome"
drawerType= 'back'
overlayColor="transparent"
gestureHandlerProps
drawerStyle={{
backgroundColor: '#c6cbef',
width: 240,
}}
>
<Drawer.Screen name="NavHome" component={HomePageTabScreen} />
<Drawer.Screen name="About Us" component={AboutScreen} />
</Drawer.Navigator>
</NavigationContainer>
)
}
export default AppNavigator;
Issue screen recording : video link
Related
When I configure my links and url-scheme with react navigation it falls into the fallback error. Don't know why. Sometimes when making changes it worked but then it didn't. I have followed some tutorials that worked perfectly but when configuring it in my app It doesn't work. Please help. this is the code:
import React, { useState, useEffect } from 'react';
import { View, Text } from 'react-native';
// NAVIGATION
import { LinkingOptions, NavigationContainer } from '#react-navigation/native';
import { createNativeStackNavigator } from '#react-navigation/native-stack';
import { SafeAreaProvider } from 'react-native-safe-area-context';
import Ionic from 'react-native-vector-icons/Ionicons';
//APP SCREENS
import AppScreens from '../../Screens/App';
// CHECK OUT NAVIGATOR GROUPS
// AUTH SCREENS
import AuthScreens from '../../Screens/Auth';
import { createBottomTabNavigator } from '#react-navigation/bottom-tabs';
import { useSelector } from 'react-redux';
import store from '../../Store';
type RootState = ReturnType<typeof store.getState>;
export type RootStackParamList = {
Login: undefined;
SignUp: undefined;
Wizard: undefined;
};
const WizardStack = createNativeStackNavigator<RootStackParamList>();
const WizardStackScreen = () => {
return (
<WizardStack.Navigator>
<WizardStack.Screen
options={() => ({
headerShown: false,
})}
name="Wizard"
component={AuthScreens.Wizard}
/>
<WizardStack.Screen
options={() => ({
headerShown: true,
})}
name="Login"
component={AuthScreens.Login}
/>
<WizardStack.Screen
options={() => ({
headerShown: true,
})}
name="SignUp"
component={AuthScreens.SignUp}
/>
</WizardStack.Navigator>
);
};
const AppStack = createNativeStackNavigator();
const AppStackScreen = () => {
return (
<AppStack.Navigator>
<AppStack.Screen
options={() => ({
headerShown: false,
})}
name="App"
component={TabScreens}
/>
</AppStack.Navigator>
);
};
const App = () => {
const [isLoading, setIsLoading] = useState(false);
const [userLoaded, setUserLoaded] = useState(false);
const userLogged = useSelector((state: RootState) => state.auth.logged);
useEffect(() => {
if (userLogged) {
setUserLoaded(true);
}
}, [userLogged]);
const config = {
screens: {
Wizard: 'wizard',
Login: 'login',
SignUp: 'signup',
},
};
const linking: LinkingOptions<RootStackParamList> = {
prefixes: ['clientsapp://app'],
config,
};
return (
<SafeAreaProvider>
{isLoading ? (
<AuthScreens.Splash />
) : (
<NavigationContainer
// linking={linking}
fallback={
<View
style={{
flex: 1,
justifyContent: 'center',
alignItems: 'center',
}}>
<Text>Loading... error</Text>
</View>
}>
<WizardStackScreen />
</NavigationContainer>
)}
</SafeAreaProvider>
);
};
export default App;
i've been trying to hide tabBar in specific screens, tried out some solutions found but none worked for me(Using Native-Base) for UI.
I have a TabNavigator in which i pass a Stack with screens.
So what i'm trying to do is to hide the TabBar in one of those screens.
See my code below 👇.
import React from 'react';
import {createBottomTabNavigator} from '#react-navigation/bottom-tabs';
import {createStackNavigator} from '#react-navigation/stack';
import { NativeBaseProvider } from 'native-base';
const Tab = createBottomTabNavigator();
const Stack = createStackNavigator();
//Stack of Screens linked with the search Menu.
function Recherche() {
return (
<Stack.Navigator initialRouteName="Recherche">
<Stack.Screen
name="Recherche"
component={Search}
options={{title: 'Recherche', headerShown: false}}
/>
<Stack.Screen
name="ViewCarte"
component={ViewCarte}
options={{title: 'ViewCarte', headerShown: false}}
/>
</Stack.Navigator>
);
}
//Stack of Screens linked with the Mon Espace Menu.
function MonEspace() {
return (
<Stack.Navigator initialRouteName="Espace">
<Stack.Screen
name="Espace"
component={Espace}
options={{title: 'Espace', headerShown: false}}
/>
<Stack.Screen
name="Compte"
component={Compte}
options={{title: 'Compte', headerShown: false}}
/>
</Stack.Navigator>
);
}
//Function constructing the TabBar
function ViewLoc({navigation}) {
return (
<NativeBaseProvider>
<Tab.Navigator
initialRouteName="Recherche"
tabBarOptions={{
activeTintColor: '#0B3D91',
style: {
padding: 5,
height: 60,
},
tabStyle: {
paddingTop: 8,
paddingBottom: 8,
},
}}>
<Tab.Screen
name="Recherche"
component={Recherche}
options={{
tabBarIcon: ({color, size}) => (
<SearchIcon color={color} size={size} />
),
}}
/>
<Tab.Screen
name="Mon espace"
component={MonEspace}
options={{
tabBarIcon: ({color, size}) => <ProfileIcon color={color} />,
tabBarVisible: true,
}}
/>
</Tab.Navigator>
</NativeBaseProvider>
);
}
Trying to hide tabBar in screen "ViewCarte" and screen "Compte".
you can change navigation structure, your structure should be like this
const RootStack = createStackNavigator();
const Tab = createBottomTabNavigator();
function TabsNavigatorComponent() {
return (
<Tab.Navigator>
//any screen or stack here will show with tabs.
</Tab.Navigator>
)
}
<NavigationContainer>
//the main Navigator shoud be Stack
<RootStack.Navigator>
//outside any screen to here, to show it without tabs.
<RootStack.Screen name="screenWithoutTabs" component={ScreenWithoutTabs}/>
<RootStack.Screen name="bottomTabs" component={TabsNavigatorComponent}/>
</RootStack.Navigator>
</NavigationContainer>
Recently, I am designing an app. And here's the problem when I combine two navigations into one.
How can I open the drawer when the screen is inside tab navigation. Android OS doesn't support a swipe left gesture. Therefore I have to add a menu button for Android users.
Is there any method to call out the drawer?
function DrawerNav() {
return (
<Drawer.Navigator
drawerContent={(props) => <DrawerContent {...props} />}
initialRouteName="Home"
>
<Drawer.Screen name="Home" component={TabNav} />
</Drawer.Navigator>
);
}
function TabNav() {
return (
<Tab.Navigator
tabBarOptions={{
showLabel: false,
style: {
flex: 1,
position: "absolute",
bottom: "5%",
left: "5%",
right: "5%",
height: win.height * 0.08,
elevation: 0,
backgroundColor: "#f7f7f7",
borderRadius: 15,
...styles.shadow,
paddingVertical: "5%",
paddingHorizontal: "5%",
},
}}
>//Some screen here
),
}}
/>
</Tab.Navigator>
);
}
function App() {
return (
<NavigationContainer>
<DrawerNav />
</NavigationContainer>
);
}
function Feed({ navigation }) {
return (
<SafeAreaView style={styles.container}>
<TouchableOpacity
onPress={() => navigation.dispatch(DrawerActions.openDrawer())}
>
<Image
source={require("./app/assets/menu.png")}
style={{ position: "absolute", top: 10, width: 40, height: 40 }}
/>
</TouchableOpacity>
</SafeAreaView>
);
}
function App() {
return (
<NavigationContainer>
<DrawerNav />
</NavigationContainer>
);
}
You can use like that you need to put your tab navigation into the drawer navigation it will be available in your all tabs screens. i am using stack navigation but its same for tab navigation
import React from 'react';
import {
SafeAreaView,
StyleSheet,
ScrollView,
View,
Text,
StatusBar,
} from 'react-native';
import Home from "./screen/Home"
import { NavigationContainer } from '#react-navigation/native';
import { createBottomTabNavigator } from '#react-navigation/bottom-tabs';
import { createStackNavigator } from '#react-navigation/stack';
import Search from "./screen/Search"
import Login from "./screen/Login"
import SuperRegister from "./screen/SuperRegister"
import CustomDrawer from "./Components/CustomDrawer"
import { createDrawerNavigator } from '#react-navigation/drawer';
import {MyContextprovider} from"./Context";
const Stack = createStackNavigator();
function MyStack(){
return (
<Stack.Navigator
headerMode={false}
initialRouteName="Login"
>
<Stack.Screen name="SuperRegister" component={SuperRegister} />
<Stack.Screen name="Login" component={Login} />
<Stack.Screen name="Home" component={Home} />
<Stack.Screen name="Search" component={Search} />
</Stack.Navigator>
);
}
const Drawer = createDrawerNavigator();
App = () => {
return (
<NavigationContainer>
<Drawer.Navigator
drawerContent={(props)=><CustomDrawer {...props} />}
>
<Drawer.Screen name="Home" component={MyStack} />
</Drawer.Navigator>
</NavigationContainer>
);
}
export default () => {
return (
<MyContextprovider>
<App />
</MyContextprovider>
)
}
for open or close drawer you can use
navigation.dispatch(DrawerActions.openDrawer());
navigation.dispatch(DrawerActions.closeDrawer());
navigation.dispatch(DrawerActions.toggleDrawer());
for refrains ..drawer ref..
I am very new to react native and this is my 1st application my org has given me to do a PoC for the same.
My requirement is i have to develop an app with
Login screen -----> Navigation Drawer(1) screen Name-- workProcessor and 2) Operation Analytics)
I am able to achieve screen at 2 different level's
i.e i am able to design Login screen and i am able to design workprocessor and operation analytics screen and switch between them
I am not able to Integrate my login screen and on click of login i should navigate to Navigation-drawer screen
My files are :
Login.js
import React from 'react';
import {
ScrollView,
Text,
TextInput,
View,
Button,
StyleSheet
} from 'react-native';
import Logo from './Logo';
import Form from './Form';
export default class Login extends React.Component {
render() {
return (
<View style={styles.container}>
<Logo></Logo>
<Form type = "Login"></Form>
<View style ={styles.workSpaceText}>
<Text style = {styles.workSpaceText}> Change WorkSpace ?</Text>
</View>
</View>
)
}
}
const styles = StyleSheet.create({
container: {
backgroundColor: '#455a64',
flex: 1,
alignItems: 'center',
justifyContent: 'center'
},
workSpaceText: {
flexGrow:1,
justifyContent:'center',
alignItems:'center',
},
workSpaceText: {
fontSize: 15,
marginVertical:15,
color: 'rgba(255,255,255,0.7)'
}
});
Form.js
import React from 'react';
import { StyleSheet, TextInput, View, Image, TouchableOpacity, Text } from "react-native";
import { useNavigation } from '#react-navigation/native';
// import { Actions } from 'react-native-router-flux';
const Form = () => {
const navigation = useNavigation();
loginMove= ()=>{
navigation.navigate('Landing');
}
return (
<View style={styles.container}>
<TextInput style={styles.inputBox}
underlineColorAndroid='rgba(0,0,0,0)'
placeholder="Username"
placeholderTextColor='#ffffff'
/>
<TextInput style={styles.inputBox}
underlineColorAndroid='rgba(0,0,0,0)'
placeholder="Password"
placeholderTextColor='#ffffff'
/>
<TouchableOpacity style={styles.button} onPress={loginMove}>
<Text style={styles.buttonText}>Login</Text>
</TouchableOpacity>
</View>
);
}
export default Form;
const styles = StyleSheet.create({
container: {
flexGrow: 1,
justifyContent: 'center',
alignItems: 'center'
},
inputBox: {
width: 300,
backgroundColor: 'rgba(255,255,255,0.5)',
borderRadius: 25,
paddingHorizontal: 16,
fontSize: 16,
color: '#ffffff',
marginVertical: 10
},
button: {
width: 300,
backgroundColor: '#1c313a',
borderRadius: 25,
marginVertical: 20,
paddingVertical: 12
},
buttonText: {
fontSize: 16,
fontWeight: '500',
color: '#ffffff',
textAlign: 'center'
}
});
And my Drawer File
i.e LandingScreen.js
/**
* Sample React Native App
* https://github.com/facebook/react-native
*
* #format
* #flow strict-local
*/
import React from 'react';
// import { Router, Stack, Scene } from 'react-native-router-flux';
import 'react-native-gesture-handler';
import { NavigationContainer } from '#react-navigation/native';
import { createStackNavigator } from '#react-navigation/stack';
import { createDrawerNavigator } from '#react-navigation/drawer';
import WorkProcessor from './workprocessor';
import OperationAnalytics from './OperationAnalytics';
import { Button, View, Text, TouchableOpacity, Image } from 'react-native';
const Stack = createStackNavigator();
const Drawer = createDrawerNavigator();
const NavigationDrawerStructure = (props) => {
//Structure for the navigatin Drawer
const toggleDrawer = () => {
//Props to open/close the drawer
props.navigationProps.toggleDrawer();
};
return (
<View style={{ flexDirection: 'row' }}>
<TouchableOpacity onPress={() => toggleDrawer()}>
{/*Donute Button Image */}
<Image
source={{ uri: 'https://raw.githubusercontent.com/AboutReact/sampleresource/master/drawerWhite.png' }}
style={{ width: 25, height: 25, marginLeft: 5 }}
/>
</TouchableOpacity>
</View>
);
}
function firstScreenStack({ navigation }) {
return (
<Stack.Navigator initialRouteName="FirstPage">
<Stack.Screen
name="FirstPage"
component={WorkProcessor}
options={{
title: 'Work-Processor', //Set Header Title
headerLeft: () => <NavigationDrawerStructure navigationProps={navigation} />,
headerStyle: {
backgroundColor: '#f4511e', //Set Header color
},
headerTintColor: '#fff', //Set Header text color
headerTitleStyle: {
fontWeight: 'bold', //Set Header text style
},
}}
/>
</Stack.Navigator>
);
}
function secondScreenStack({ navigation }) {
return (
<Stack.Navigator
initialRouteName="SecondPage"
screenOptions={{
headerLeft: () => <NavigationDrawerStructure navigationProps={navigation} />,
headerStyle: {
backgroundColor: '#f4511e', //Set Header color
},
headerTintColor: '#fff', //Set Header text color
headerTitleStyle: {
fontWeight: 'bold', //Set Header text style
}
}}>
<Stack.Screen
name="SecondPage"
component={OperationAnalytics}
options={{
title: 'Operational Analytics', //Set Header Title
}} />
</Stack.Navigator>
);
}
const LandingScreen = () => (
<NavigationContainer>
<Drawer.Navigator
drawerContentOptions={{
activeTintColor: '#e91e63',
itemStyle: { marginVertical: 5 },
}}>
<Drawer.Screen
name="FirstPage"
options={{ drawerLabel: 'Work-Processor' }}
component={firstScreenStack} />
<Drawer.Screen
name="SecondPage"
options={{ drawerLabel: 'Operation-Analytics' }}
component={secondScreenStack} />
</Drawer.Navigator>
</NavigationContainer>
);
export default LandingScreen;
When i am clicking on login button i.e loginMove .. it is not moving to navigation drawer screen and giving 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}' explicitely. Note that this will make the child navigators disconnected from the parent and you won't be able to navigate between them.
Please can some one help me completing this flow. I am ready for doing any code changes it's my PoC
You cannot embedd NavigationContainer, only stacks, drawers, tabs, etc
I suggest you to make two Navigations, one for login, one logged. This prevent to back to login screen when already logged in.
Example
// App.js
return(
<NavigationContainer>
{isLogged ? <LoggedNav /> : <LoginNav />}
</NavigationContainer>
)
With your Drawer in LoggedNav and Stacks in LoginNav
OR
In a first stack, you have a screen with your drawer stack and one with your landing page stack. You can embedd stacks as much as you want but not NavigationContainer. A screen can be a stack without problems.
function Login({ navigation }) {
return (
<Stack.Navigator initialRouteName="FirstPage">
<Stack.Screen
name="FirstPage"
component={WorkProcessor}
options={{
title: 'Work-Processor', //Set Header Title
headerLeft: () => <NavigationDrawerStructure navigationProps={navigation} />,
headerStyle: {
backgroundColor: '#f4511e', //Set Header color
},
headerTintColor: '#fff', //Set Header text color
headerTitleStyle: {
fontWeight: 'bold', //Set Header text style
},
}}
/>
</Stack.Navigator>
);
}
const LandingScreen = () => (
<Drawer.Navigator
drawerContentOptions={{
activeTintColor: '#e91e63',
itemStyle: { marginVertical: 5 },
}}>
<Drawer.Screen
name="FirstPage"
options={{ drawerLabel: 'Work-Processor' }}
component={firstScreenStack} />
<Drawer.Screen
name="SecondPage"
options={{ drawerLabel: 'Operation-Analytics' }}
component={secondScreenStack} />
</Drawer.Navigator>
);
return(
<NavigationContainer>
<Stack.Navigator initialRouteName="login">
<Stack.Screen name="login" component={Login} ... />
<Stack.Screen name="landing" component={LandingScreen} ... />
</Stack.Navigator>
</NavigationContainer>
)
I have this code in App.js (I'm using CRNA create-react-native-app).
import React from 'react';
import {StyleSheet, Text, View, Button, Navigator, Image} from 'react-native';
import {Container, Content, Header, Body, Icon} from 'native-base';
import UserLocation from './pages/UserLocation';
import ShopNow from './pages/ShopNow';
import ItemFavorite from './pages/ItemFavorite';
import {createStackNavigator,createDrawerNavigator, DrawerItems} from 'react-navigation';
export default class App extends React.Component {
constructor(props) {
super(props);
}
static navigationOptions = {
title:'Welcome',
headerLeft:
<View style={{paddingLeft:16}}>
<Icon
name="md-menu"
size={30}
color='black'
onPress={() => navigation.navigate('DrawerOpen')} />
</View>
}
render() {
return (
<AppStackNavigator/>
//<MyAppDrawer/>
);
}
}
const CustomDrawer = (props) => (
<Container>
<Header style={{
height:200
}}>
<Body>
<Image
style={styles.drawerImage}
source={require('./images/logo.png')}
/>
</Body>
</Header>
<Content>
<DrawerItems {...props} />
</Content>
</Container>
)
const MyAppDrawer = createDrawerNavigator({
Home: {
screen: UserLocation
},
Shop: {
screen: ShopNow
},
Favorite: {
screen: ItemFavorite
}
},{
initialRouteName: 'Home',
contentComponent: CustomDrawer,
drawerOpenRoute: 'DrawerOpen',
drawerCloseRoute: 'DrawerClose',
drawerToggleRoute: 'DrawerToggle'
});
const AppStackNavigator = createStackNavigator({
Drawer: {screen: MyAppDrawer},
App: {
screen: UserLocation,
// navigationOptions:{
// title:'Welcome',
// headerLeft:
// <View style={{paddingLeft:16}}>
// <Icon
// name="md-menu"
// size={30}
// color='black'
// onPress={() => navigation.navigate('DrawerOpen')} />
// </View>
// }
},
ShopNow: { screen: ShopNow },
ItemFavorite: { screen: ItemFavorite}
});
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center',
},
drawerImage: {
height: 150,
width: 150,
borderRadius: 75
}
});
I don't know why anywhere I put the static navigationOptions, it doesn't change the header of the first page.
I also tried using the static navigationOptions.headerLeft in the specific page to add hamburger-icon, it doesn't work.
But in the page 'ItemFavorite' at the bottom of the file I set this:
ItemFavorite.navigationOptions = {
drawerIcon: (
<Image source={require('../images/tablet.png')} style={{ height: 24, width: 24 }} />
),
title: 'Favorite Item',
headerLeft: <Text onPress={() =>
navigation.navigate('DrawerOpen')}>Menu</Text>
}
it works! But not working in the first page of stack.
Do I miss something here?
You need put Your View in same line as headerLeft
import React from 'react';
import {StyleSheet, Text, View, Button, Navigator, Image} from 'react-native';
import {Container, Content, Header, Body, Icon} from 'native-base';
import UserLocation from './pages/UserLocation';
import ShopNow from './pages/ShopNow';
import ItemFavorite from './pages/ItemFavorite';
import {createStackNavigator,createDrawerNavigator, DrawerItems} from 'react-navigation';
export default class App extends React.Component {
constructor(props) {
super(props);
}
static navigationOptions = {
title:'Welcome',
headerLeft: <View style={{paddingLeft:16}}>
<Icon
name="md-menu"
size={30}
color='black'
onPress={() => navigation.navigate('DrawerOpen')} />
</View>
}
render() {
return (
<AppStackNavigator/>
//<MyAppDrawer/>
);
}
}