What is the right way to setup navigation drawer in react native - android

Hello guys im a react native beginner and i created some small projects but in everyone of them my navigation is wrong ( works but not as i wanted ) exactly on the drawer look at my code and as you can see the MainStack , Login and StartUpScreen are showing on the drawer when open it in the app and i don't want that ! i just put them there so i can navigate between them ! is there any better way or someone who can show me how to do it right ?
const RootNavigation = (props) => {
const Stack = createStackNavigator();
const Drawer = createDrawerNavigator();
const screenOptions = {
headerShown: true,
headerStyle: {
backgroundColor: "white",
},
headerTintColor: "aqua",
headerTitleStyle: {
fontWeight: "bold",
},
};
const drawerOptions = {
headerShown: false,
};
const AppStack = () => (
<Stack.Navigator
initialRouteName="ProductsOverview"
screenOptions={screenOptions}
>
<Stack.Screen
name="ProductsOverview"
component={ProductsOverviewScreen}
options={({ navigation, route }) => ({
title: "All Products",
headerTitleStyle: { fontFamily: "open-sans-bold" },
headerRight: () => (
<HeaderButtons HeaderButtonComponent={HeaderButton}>
<Item
title="Cart"
iconName={Platform.OS === "android" ? "md-cart" : "ios-cart"}
onPress={() => {
navigation.navigate("CartScreen");
}}
/>
</HeaderButtons>
),
})}
/>
<Stack.Screen
name="ProductsDetail"
component={ProductDetails}
options={({ route }) => ({
title: route.params.productTitle,
headerTitleStyle: { fontFamily: "open-sans-bold" },
})}
/>
<Stack.Screen
name="CartScreen"
component={CartScreen}
options={{
title: "Cart Items",
headerTitleStyle: { fontFamily: "open-sans-bold" },
}}
/>
<Stack.Screen
name="OrdersScreen"
component={OrdersScreen}
options={{
title: "Orders ",
headerTitleStyle: { fontFamily: "open-sans-bold" },
}}
/>
<Stack.Screen
name="EditingProductScreen"
component={EditingProductScreen}
options={({ navigation }) => ({
title: "Editing",
headerTitleStyle: { fontFamily: "open-sans-bold" },
headerLeft: () => (
<HeaderButtons HeaderButtonComponent={HeaderButton}>
<Item
title="Cart"
iconName={
Platform.OS === "android" ? "md-arrow-back" : "ios-arrow-back"
}
onPress={() => {
navigation.navigate("User Products");
}}
/>
</HeaderButtons>
),
})}
/>
<Stack.Screen
name="AddingProductScreen"
component={AddingProductScreen}
options={({ navigation }) => ({
title: "Adding",
headerTitleStyle: { fontFamily: "open-sans-bold" },
headerLeft: () => (
<HeaderButtons HeaderButtonComponent={HeaderButton}>
<Item
title="Cart"
iconName={
Platform.OS === "android" ? "md-arrow-back" : "ios-arrow-back"
}
onPress={() => {
navigation.navigate("User Products");
}}
/>
</HeaderButtons>
),
})}
/>
</Stack.Navigator>
);
function CustomDrawerContent(props) {
const dispatch = useDispatch();
return (
<DrawerContentScrollView {...props}>
<DrawerItemList {...props} />
<Button
title="LOGOUT"
onPress={() => {
dispatch(authActions.logout());
}}
/>
</DrawerContentScrollView>
);
}
return (
<NavigationContainer ref={navigationRef}>
<Drawer.Navigator
screenOptions={drawerOptions}
drawerContent={(props) => <CustomDrawerContent {...props} />}
>
<Drawer.Screen name="StartUpScreen" component={StartUpScreen} />
<Drawer.Screen name="Login" component={Login} />
<Drawer.Screen name="MainStack" component={AppStack} />
<Drawer.Screen
name="Products Overview"
component={ProductsOverviewScreen}
options={({ navigation, route }) => ({
headerShown: true,
title: "All Products",
headerTitleStyle: { fontFamily: "open-sans-bold" },
headerStyle: {
backgroundColor: "white",
},
headerTintColor: "aqua",
headerTitleStyle: {
fontWeight: "bold",
},
headerRight: () => (
<HeaderButtons HeaderButtonComponent={HeaderButton}>
<Item
title="Cart"
iconName={Platform.OS === "android" ? "md-cart" : "ios-cart"}
onPress={() => {
navigation.navigate("CartScreen");
}}
/>
</HeaderButtons>
),
})}
/>
<Drawer.Screen
name="Orders"
component={OrdersScreen}
options={{
headerShown: true,
title: "Orders ",
headerTitleStyle: { fontFamily: "open-sans-bold" },
headerStyle: {
backgroundColor: "white",
},
headerTintColor: "aqua",
headerTitleStyle: {
fontWeight: "bold",
},
}}
/>
<Drawer.Screen
name="User Products"
component={userProducts}
options={({ navigation }) => ({
headerShown: true,
title: "User Products",
headerTitleStyle: { fontFamily: "open-sans-bold" },
headerStyle: {
backgroundColor: "white",
},
headerTintColor: "aqua",
headerTitleStyle: {
fontWeight: "bold",
},
headerRight: () => (
<HeaderButtons HeaderButtonComponent={HeaderButton}>
<Item
title="Cart"
iconName={Platform.OS === "android" ? "md-add" : "ios-add"}
onPress={() => {
navigation.navigate("AddingProductScreen");
}}
/>
</HeaderButtons>
),
})}
/>
</Drawer.Navigator>
</NavigationContainer>
);
};
export default RootNavigation;

Related

Drawer open automatically on navigate or Tab Change [ ReactNative ]

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

react-native Hide specific label of screen in the bottom tab navigation

I have total 6 screens, however I only want to put 4 screens(Tutorial, File Upload, Details Search, and Profile) in the bottom tab navigation below the screen. I use " tabBarLabel: () => null " to hide label for login and register screens.
My bottom tab now has 4 labels, but only the label has disappeared and still occupies that place.
enter image description here
const Tabs = createBottomTabNavigator();
const Stack = createStackNavigator();
const FileUploadStack = ({route, navigation}) => (
<Stack.Navigator screenOptions={{
headerStyle: {
backgroundColor: '#009387',
},
headerTintColor: '#fff',
headerTitleStyle: {
fontWeight: 'bold'
}
}}>
<Stack.Screen name="File Upload" component={FileUpload} initialParams={{ itemId: 42 }} options={{
title:''}} />
</Stack.Navigator>
);
const DetailsSearchStack = ({navigation}) => (
<Stack.Navigator screenOptions={{
headerStyle: {
backgroundColor: '#009387',
},
headerTintColor: '#fff',
headerTitleStyle: {
fontWeight: 'bold'
}
}}>
<Stack.Screen name="Details Search" component={DetailsSearch} options={{
title:''}} />
</Stack.Navigator>
);
const LoginStack = ({navigation}) => (
<Stack.Navigator screenOptions={{
headerStyle: {
backgroundColor: '#009387',
},
headerTintColor: '#fff',
headerTitleStyle: {
fontWeight: 'bold'
}
}}>
<Stack.Screen name="Login" component={Login} options={{
title:''}} />
</Stack.Navigator>
);
const RegisterStack = ({navigation}) => (
<Stack.Navigator screenOptions={{
headerStyle: {
backgroundColor: '#009387',
},
headerTintColor: '#fff',
headerTitleStyle: {
fontWeight: 'bold'
}
}}>
<Stack.Screen name="Register" component={Register} options={{
title:'' }} />
</Stack.Navigator>
);
const TutorialStack = ({navigation}) => (
<ThemeContextProvider>
<Stack.Navigator screenOptions={{
headerStyle: {
backgroundColor: '#009387',
},
headerTintColor: '#fff',
headerTitleStyle: {
fontWeight: 'bold'
}
}}>
<Stack.Screen name="Tutorial" component={Tutorial} options={{
title:'' }} />
</Stack.Navigator>
</ThemeContextProvider>
);
export default function App() {
const [value1, setValue1] = useState("");
const [value2, setValue2] = useState("");
return (
<NavigationContainer>
<Tabs.Navigator>
<Tabs.Screen name = "Tutorial" component={Tutorial} options={{ tabBarVisible: false, header: null}}/>
<Tabs.Screen name= "Login" component={Login} options={{ tabBarVisible: false, tabBarLabel: () => null}}/>
<Tabs.Screen name= "Register" component={Register} options={{ tabBarVisible: false,tabBarLabel: () => null }}/>
<Tabs.Screen name= "File Upload" component={FileUpload} />
<Tabs.Screen name= "Details Search" component={DetailsSearch} />
<Tabs.Screen name = "Profile" component={User} option={{ tabBarLabel: 'Profile',
tabBarIcon: ({ color }) => ( <View>
<Icon name={"ios-person"} color={color} size={25}/> </View>)}}/>
</Tabs.Navigator>
{/* <Stack.Navigator initialRouteName="Tutorial">
<Stack.Screen name="Tutorial" component={Tutorial} options={{ headerShown: false }}/>
<Stack.Screen name="Login" component={Login}/>
<Stack.Screen name="Register" component={Register}/>
<Stack.Screen name="File Upload" component={FileUpload} />
<Stack.Screen name="Details Search" component={DetailsSearch}/>
</Stack.Navigator> */}
{/* <FlatList
data={data}
renderItem={({ item }) => (
<Text>{item.field1}, {item.field2}</Text>
)}
/> */}
<StatusBar style="auto" />
</NavigationContainer>
);
}
You will have to return null for the tabBarButton like below, this will hide the whole button from the tabbar
<Tab.Screen
name="Home"
component={HomeScreen}
options={{
tabBarButton: () => null,
}}
/>

I am getting default header in the react-native android ,How to fix that header?

enter image description hereHow I can change that header in the react-native, After giving build I am getting that default android header.Please me out with this issue
<NavigationContainer>
<Stack.Navigator
screenOptions={{
headerTransparent: false,
headerTitleAlign: "center",
headerTitleStyle: {
fontSize: 13,
fontWeight: "normal",
letterSpacing: 1,
color: "#fff",
},
headerStyle: {
backgroundColor: "#7862FF",
},
headerTintColor: "#fff",
headerBackTitleVisible: false,
}}
>
{loginState.userToken == null ? (
<>
<Stack.Screen
name="Login"
component={SignInScreen}
options={{ headerShown: false }}
/>
<Stack.Screen
name="SignUp"
component={SignUpScreen}
options={{ headerShown: false }}
/>
<Stack.Screen
name="Forgotpassword"
component={Forgetpassword}
options={{ headerShown: false }}
/>
</>
) : (
<>
<Stack.Screen
name="Landing"
component={LandingScreen}
options={{ headerShown: false }}
/>
<Stack.Screen
name="Dashboard"
component={DashboardScreen}
options={{ title: "Dashboard", headerTransparent: false }}
/>
<Stack.Screen
name="ArCamera"
component={CreateArTag}
options={{ title: "", headerTransparent: true }}
/>
<Stack.Screen
name="ViewArTag"
component={ViewArTag}
options={{ title: "", headerTransparent: true }}
/>
</>
)}
</Stack.Navigator>
</NavigationContainer>

React native navigation drawer is not covering header in my application

I am new to react native development, but i have some requirement with react navigation drawer. I want to display the navigation drawer from top of the screen but it is display below from toolbar. It is a combination of both Stack and Drawer screens. Following is my code in App.js
function App() {
SplashScreen.hide()
return (
<NavigationContainer>
{/* headerMode='float' */}
<Stack.Navigator initialRouteName='Login' >
<Stack.Screen name="Login" component={LoginScreen}
options={{ headerShown: false }} />
{/* <Stack.Screen name="Home" component={HomeScreen} /> */}
<Stack.Screen name="DrawerScreens" component={DrawerScreens}
options={({ navigation, route }) => ({
title: "Home",
headerTintColor: '#FFFFFF', headerStyle:{backgroundColor:'#154493'},
headerLeft: props => <NavigationDrawerStructure navObj={navigation} />,
})} />
<Stack.Screen name="Dashboard" component={Dashboard}
options={({ route }) => ({headerTintColor: '#FFFFFF', headerStyle:{backgroundColor:'#154493'}})} />
</Stack.Navigator>
</NavigationContainer>
DrawerScreens function is like following..
function DrawerScreens({ route, navigation }) {
// console.log("param:"+route.params.token)
return (
//drawerContent={props=>CustomDrawerContent(props)}
// <SafeAreaProvider>
<Drawer.Navigator drawerContent={props => CustomDrawerContent(props)} headerMode="float" >
{/* <Drawer.Navigator drawerContent={props => CustomDrawerContent(props)}> */}
{/* options={{ drawerLabel: 'Updates' }} */}
<Drawer.Screen name="LandingScreen" component={LandingScreen}
initialParams={{ token: route.params.token }}/>
);
}
CustomDrawer function contains list of the menu items which is dynamic and NestedMenuView is taking care of that..
function CustomDrawerContent(props) {
return (
<SafeAreaView style={{flex: 1}} forceInset={{ top: "always" }}>
<NestedMenuView navObj={props.navigation} />
</SafeAreaView>
);
};
For me the combination of both stack and drawer screens.Thanks in advance.
I don't think the problem lies around the Stack Navigator or the Screen components;
If you use the latest, after v5 release version of #react-navigation/drawer (mine is 5.6.3) the recommended way is to use the built-in wrappers when creating custom drawer
const Drawer = createDrawerNavigator();
const Menu = (props) => {
return (
<DrawerContentScrollView {...props}>
<DrawerItemList {...props} />
<DrawerItem label="Help" onPress={() => {}} />
</DrawerContentScrollView>
);
};
export default function MyDrawer() {
return (
<Drawer.Navigator
initialRouteName="Tabs"
drawerContent={(props) => <Menu {...props} />}
edgeWidth={100}
drawerContentOptions={{
activeTintColor: Colors.accentColor,
labelStyle: {
fontFamily: 'open-sans',
},
}}
>
<Drawer.Screen...
</Drawer.Navigator>
);
You can also leave the scrollview and create custom ui like this:
const contentOptions = {
activeBackgroundColor: '#dbdbdb',
activeLabelStyle: {
fontSize: 16,
color: 'black',
fontFamily: 'roboto'
},
labelStyle: {
fontSize: 16,
fontWeight: 'normal',
color: intenseGrey,
fontFamily: 'roboto'
}
};
return (
<View
style={{
display: 'flex',
flexDirection: 'column',
flexGrow: 1
}}
>
<SafeAreaView style={{ flex: 1, paddingBottom: 0 }}>
<View style={{
backgroundColor: '#dbdbdb',
display: 'flex',
flexDirection: 'column',
justifyContent: 'space-between',
flexGrow: 1}}
>
<View>
<DrawerItemList {...props} {...contentOptions} />
</View>
</View>
</SafeAreaView>
</View>
);
I think the reason that Drawer is not covering is because you put the Drawer navigation inside your Stack navigation.
Yours
Stack
Drawer
To fixed that you have to readjust the order
Drawer
Stack
For example (or you could see from my snack here: https://snack.expo.io/#gie3d/d25aca)
const HomeStack = () => (
<Stack.Navigator>
<Stack.Screen name="Home" component={Home} options={({navigation}) => ({
title: "Home",
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>
);
}
The following stacks created and calling these stacks from Drawer Screens.
const LandingStack = ({ route, navigation }) => (
<Stack.Navigator>
<Stack.Screen name="LandingScreen" component={LandingScreen} options={({navigation}) => ({
headerTitle: 'Home',
headerTintColor: '#FFFFFF', headerStyle:{backgroundColor:'#000' },
headerLeft: props => <NavigationDrawerStructure navObj={navigation} />,
})} />
</Stack.Navigator>
);
const TicketingStack = () => (
<Stack.Navigator>
<Stack.Screen name="TicketingDashboard" component={TicketingDashboard} options={({route, navigation}) => ({
headerTitle: route.params.type,
headerTintColor: '#FFFFFF', headerStyle:{backgroundColor:'#000' },
headerLeft: props => <NavigationDrawerStructure navObj={navigation} />,
})} />
</Stack.Navigator>
);
function DrawerScreens({ route, navigation }) {
// console.log("param:"+route.params.token)
return (
//drawerContent={props=>CustomDrawerContent(props)}
<SafeAreaProvider>
<Drawer.Navigator drawerContent={props => CustomDrawerContent(props)} headerMode="screen">
{/* options={{ drawerLabel: 'Updates' }} */}
{/* <Stack.Screen name="DrawerScreens" component={DrawerScreens}
options={({ navigation, route }) => ({
title: "Home",
headerTintColor: '#FFFFFF', headerStyle:{backgroundColor:'#000' },
headerLeft: props => <NavigationDrawerStructure navObj={navigation} />,
})} /> */}
<Drawer.Screen name="LandingStack" component={LandingStack}
initialParams={{ token: route.params.token }}/>
<Drawer.Screen name="HomeStack" component={HomeStack}
initialParams={{ token: route.params.token }} />
</Drawer.Navigator>
</SafeAreaProvider>
);
}
And I have removed header part from the function App and finally looks like this in the App.js
<Stack.Screen name="DrawerScreens" component={DrawerScreens}
options={{ headerShown: false }} />

React Native: expected a string (for built-in components) or a class/function (for composite components) but got: object

I am trying to change the Header Title to an image, but I can't get it to work. What I have tried is use the LogoTitle class to render an image instead of a title in my Top Tab Navigator, hiding the header works and rendering a title works also:
TopNavigator.navigationOptions = {
headerTitle:'test'
};
And then I tried to change it to an image:
TopNavigator.navigationOptions = () =>{
headerTitle:<LogoTitle/>
};
I use the latest Expo SDK
This is my full code:
import React from 'react';
import { createStackNavigator, createMaterialTopTabNavigator } from 'react-navigation';
import TabBarIcon from '../components/TabBarIcon';
import PartyScreen from '../screens/PartyScreen';
import EventScreen from '../screens/EventScreen';
import FestivalScreen from '../screens/FestivalScreen';
import ActivityScreen from '../screens/ActivityScreen';
import TestScreen from '../screens/TestScreen';
class LogoTitle extends React.Component {
render() {
return (
<Image
source={require('../assets/images/Header_Logo.png')}
style={{ width: '100%', height: '100%', resizeMode: 'center', backgroundColor: 'black' }}
/>
);
}
}
const PartyStack = createStackNavigator({
Party: PartyScreen,
});
PartyStack.navigationOptions = {
tabBarLabel: "Partys",
tabBarIcon: ({ focused }) => (
<TabBarIcon
focused={focused}
name={
'md-calendar'
}
/>
),
};
const EventStack = createStackNavigator({
Event: EventScreen,
});
EventStack.navigationOptions = {
tabBarLabel: 'Events',
tabBarIcon: ({ focused }) => (
<TabBarIcon
focused={focused}
name={
'md-calendar'
}
/>
),
};
const FestivalStack = createStackNavigator({
Festival: FestivalScreen,
});
FestivalStack.navigationOptions = {
tabBarLabel: 'Festivals',
tabBarIcon: ({ focused }) => (
<TabBarIcon
focused={focused}
name={
'md-calendar'
}
/>
),
};
const ActivityStack = createStackNavigator({
Activity: ActivityScreen,
});
ActivityScreen.navigationOptions = {
tabBarLabel: 'Activiteit',
tabBarIcon: ({ focused }) => (
<TabBarIcon
focused={focused}
name={
'md-calendar'
}
/>
),
};
const TestStack = createStackNavigator({
Test: TestScreen,
});
TestScreen.navigationOptions = {
tabBarLabel: 'Test',
tabBarIcon: ({ focused }) => (
<TabBarIcon
focused={focused}
name={
'md-calendar'
}
/>
),
};
const TopNavigator = createMaterialTopTabNavigator({
PartyStack,
EventStack,
FestivalStack,
ActivityStack,
TestStack
}, {
tabBarOptions: {
activeTintColor: '#5B71F9',
inactiveTintColor: '#888888',
showIcon: false,
labelStyle: {
fontSize: 14
},
scrollEnabled : true,
style: {
backgroundColor: '#fff',
shadowColor: '#fff',
shadowOffset: {
width: 0,
height: 0,
},
shadowOpacity: 0,
shadowRadius: 0,
elevation: 0,
height: 47,
borderBottomWidth: 1,
borderBottomColor: '#E8E8E8'
},
indicatorStyle: {
height: 2,
backgroundColor: '#5B71F9'
},
},
}, navigationOptions = {
header:{visible:false}
});
TopNavigator.navigationOptions = {
headerTitle:<LogoTitle/>
};
export default TopNavigator;
I don't get why it does render Text but images wont, I guess it has to do with the brackets
try this:
const RouteConfigs = {
// Your routes
};
const StackNavigatorConfig = {
navigationOptions: {
header: (navigation) => ({
title: ( <LogoTitle navigation={navigation} /> )
})
},
};
export default createStackNavigator(RouteConfigs, StackNavigatorConfig);

Categories

Resources