How to add clickable Icons to reactNative navbar - react-native

I want to add clickable icons to my reactnative header component
Currently it looks like this
next to the title text on the right I want to add an audio symbol but i cant figure out on doing this.
I have seen plenty of answers that work with navigation but Im using drawers so i dnt understand how to add icons.
This is what my code looks like
app.js
<NavigationContainer >
<Drawer.Navigator initialRouteName="MetalDetector" screenOptions={{
drawerStyle: {
backgroundColor: '#3e4463',
width: 220
},
}}>
<Drawer.Screen name="MetalDetector" component={Home} options={{drawerLabel: '๐Ÿ”ฆ MetalDetector'}} />
<Drawer.Screen name="Settings" component={Settings} options={{drawerLabel: '๐Ÿ›  Settings'}} />
<Drawer.Screen name="Calibrate" component={Home} options={{drawerLabel: '๐Ÿ’ก Calibration'}}/>
<Drawer.Screen name="Feedback" component={Home} options={{drawerLabel: '๐Ÿ‘จโ€๐Ÿ‘ฉโ€๐Ÿ‘งโ€๐Ÿ‘ฆ Feedback'}}/>
and this is my home.js file which renders content for the metaldetector page
<View style={styles.container}>
<View style={styles.buttonContainer}>
//Cde is below
</View>
</View>
);
}
So where would i add icons to the titlemenu?
I found this here, which covers on how to set the header using stackscreen
https://reactnavigation.org/docs/headers/
but since I use drawer.screen i dont know how to apply that

Option 1:
The DrawerContent file
import React, { useState } from 'react';
import { View, StyleSheet, Image, Alert, Text } from 'react-native';
import { Title, Drawer } from 'react-native-paper';
import { DrawerContentScrollView, DrawerItem } from '#react-navigation/drawer';
import { FontAwesome, MaterialIcons, AntDesign, Ionicons } from '#expo/vector-icons';
import colors from '../config/colors';
const AppDrawerItem = ({ label , icon, onPress, ...props }) => {
return (
<DrawerItem
icon={icon}
label={label}
onPress={onPress}
/>
);
}
export function DrawerContent(props) {
return (
<View style={{ flex: 1 }}>
<DrawerContentScrollView {...props}>
<Drawer.Section style={styles.drawerSection}>
<AppDrawerItem
onPress={() => { setIsDeletePressed(false); props.navigation.navigate('Dashboard') }}
label="Dashboard"
icon={({ color, size, focused }) => (
<MaterialIcons
name="dashboard"
color={focused ? colors.primary : color}
size={size}
/>
)}
{...props}
/>
<AppDrawerItem
onPress={() => { setIsDeletePressed(false); props.navigation.navigate('Messages') }}
label="Messages"
icon={({ color, size, focused }) => (
<MaterialIcons
name="notifications"
color={focused ? colors.primary : color}
size={size}
/>
)}
{...props}
/>
</Drawer.Section>
</DrawerContentScrollView >
</View >
);
}
DrawerNavigator
<Drawer.Navigator
screenOptions={{
headerTitleStyle: {
color: "black",
opacity: 0.9
},
headerTintColor: colors.primary,
swipeEnabled: false,
headerTitleAlign: 'center',
headerShadowVisible: false,
}} drawerContent={props => <DrawerContent {...props} />} > //---here you can add drawercontent component
<Drawer.Screen name="Dashboard" component={HomeScreen} />
<Drawer.Screen options={{ headerShown: true }} name="Messages" component={NotificationNavigator} />
</Drawer.Navigator >
Edit:
Option2:
You can add the icon in the <Drawer.Screen> tag.
<Drawer.Screen name="Feed" component={Feed} options={{
title: 'Home',
drawerIcon: ({focused, size}) => (
<Ionicons
name="md-home"
size={size}
color={focused ? '#7cc' : '#ccc'}
/>
),
}} />

Related

How do I get rid of the grey background that appears when a tab is active on my navigation tab bar React Native

There is a grey background on each icon when it is active. I am not sure how to get rid of it. I have looked everywhere and tried a lot of solutions and nothing seems to work. I'm not sure if I have been putting code in the wrong place. Or using the wrong code but it just doesn't seem to respond to anything.
Any help on this would be very appreciated if anyone knows how to fix it.
I shall attach the image of what I am getting. I just want to get rid of the grey background enter image description here
import { createNativeStackNavigator } from "#react-navigation/native-stack";
import { createMaterialBottomTabNavigator } from "#react-navigation/material-bottom-tabs";
import { Ionicons } from "#expo/vector-icons";
import { Foundation, FontAwesome5, MaterialIcons, } from "#expo/vector-icons";
import HomeScreen from "../screens/homeFolder/homeScreen";
import ProfilePage from "../screens/profilePageFolder/profilePage";
import YourShopPage from "../screens/yourShopFolder/yourShop";
import YourTicketsPage from "../screens/yourTicketFolder/yourTickets";
const Stack = createNativeStackNavigator();
const RootNavigator = () => {
return (
<Stack.Navigator screenOptions={{headerShown: true,
headerStyle:{backgroundColor: "#1d1d1d",
borderStyle: "none", }, headerTintColor: '#fff', headerTitleAlign: "center", }}>
<Stack.Screen name="HomeTabs" component={HomeTabs} />
</Stack.Navigator>
);
};
const Tab = createMaterialBottomTabNavigator();
const HomeTabs = () => {
return (
<Tab.Navigator
barStyle={{backgroundColor: "#2d2d2d"}}
activeColor="#9C3CF4"
inactiveColor="#ffffff"
>
<Tab.Screen
name="Home"
component={HomeScreen}
options={{ tabBarIcon: ({color}) => (
<Ionicons name="home-outline" size={24} color="white"/>
), tabBarActiveTintColor:"blue",
}}
/>
<Tab.Screen
name = "Your Tickets"
component={YourTicketsPage}
options={{tabBarIcon: ({color}) => (
<Ionicons name="wallet-outline" size={24} color="white"/>
),
}}
/>
<Tab.Screen
name = "Your Shop"
component={YourShopPage}
options={{tabBarIcon: ({color}) => (
<Ionicons name="business-outline" size={24} color="white" />
),
}}
/>
<Tab.Screen
name = "Profile"
component={ProfilePage}
options={{tabBarIcon: ({color}) => (
<Ionicons name="person-outline" size={24} color="white"/>
),
}}
/>
</Tab.Navigator>
);
};
export default RootNavigator;
This is my code for navigation module of my App.

React native - remove space between drawerIcon and item text on Drawer.Screen

I'm trying to adjust space between icon and text in drawer screen.
Here's an image to explain better.
Here's my code
<Drawer.Navigator screenOptions={(navigation) => ({
drawerItemStyle: {
borderRadius: 0,
width: '100%',
marginLeft: 0
}
})}>
<Drawer.Screen
name="HomeScreen"
component={HomeScreen}
options={{
headerShown: true,
headerTransparent: true,
headerTitle: "",
title: 'Start Delivery',
drawerIcon: (({focused}) => <Icon name="car" size={25} color={focused ? "#288df9" : "#777"} style={{padding:0, margin:0}} />)
}}
/>
</Drawer.Navigator>
Thanks
The default Drawer uses a DrawerItemList which is a list of DrawerItems. Looking at the source code, the view that wraps the label implements a marginLeft of 32. This is hardcoded and cannot be changed without using dirty tricks.
Let us test this using the following example.
function App() {
return (
<NavigationContainer>
<Drawer.Navigator>
<Drawer.Screen name="Home" component={Home} options={{drawerIcon: () => <View style={{height:20, width: 20, backgroundColor: "red"}} />}} />
</Drawer.Navigator>
</NavigationContainer>
);
}
The above uses a View as a dummy image with a red background. Here is the result.
Adding a marginRight of -32 to our icon removes the "gap" completely.
function App() {
return (
<NavigationContainer>
<Drawer.Navigator>
<Drawer.Screen name="Home" component={Home} options={{drawerIcon: () => <View style={{height:20, width: 20, backgroundColor: "red", marginRight: -32}} />}} />
</Drawer.Navigator>
</NavigationContainer>
);
}
Here is the result.
This is not ideal since we have to do this for each icon, thus we could create a custom component and reuse it.
const CustomIconComponent = ({focused, name}) => {
return <View style={{marginRight: -32}}>
<Icon name={name} size={25} color={focused ? "#288df9" : "#777"} />
</View>
}
Then, use it for each screen.
options={{
...
title: 'Start Delivery',
drawerIcon: (({focused}) => <CustomIconComponent focused={focused} />)
}}
There is a second way. We could create a custom drawer. This would allow us to not use the DrawerItem component but a custom component with custom stylings.

State is updating but it is not updating the new value on scrren?

I don't seem to have any problems using setState in other pages of my project but in the app.js it just does not work? I am very new to react native.
I am calling the function 'handleacount' from another page and it gets the data and I just want to update the 'Acount'
The state is updating because it alerts but it does not update when it has already been rendered? Am I missing something?
The page App.js is :
import 'react-native-gesture-handler';
import React, { useState, Component } from "react";
import { MaterialCommunityIcons } from '#expo/vector-icons';
import { NavigationContainer } from '#react-navigation/native';
import { createStackNavigator } from '#react-navigation/stack';
import { createBottomTabNavigator } from '#react-navigation/bottom-tabs';
import Constants from 'expo-constants';
import IconBadge from 'react-native-icon-badge';
import { Text, View, StyleSheet } from 'react-native';
import HomeScreen from './pages/HomeScreen';
import SearchScreen from './pages/SearchScreen';
import SettingsScreen from './pages/SettingsScreen';
import MapScreen from './pages/MapScreen';
import NotificationsScreen from './pages/NotificationsScreen';
import { ListItem, Avatar, Badge, Icon, withBadge } from 'react-native-elements'
const Stack = createStackNavigator();
const Tab = createBottomTabNavigator();
const MessagesIcon = ({ tintColor }) => (
<Icon
type="MaterialCommunityIcons"
name="checkcircle"
size={24}
color={tintColor}
/>
);
function HomeStack() {
return (
<Stack.Navigator>
<Stack.Screen
name="Home"
component={HomeScreen}
options={{ title: 'Home Page', headerShown: false }}
/>
<Stack.Screen
name="Search"
component={SearchScreen}
options={{ headerShown: false }}
/>
<Stack.Screen
name="Notifications"
component={NotificationsScreen}
options={{ headerShown: false }}
/>
<Stack.Screen
name="Map"
component={MapScreen}
changeoptions={{ headerShown: false }}
/>
<Stack.Screen
name="Settings"
component={SettingsScreen}
changeoptions={{ headerShown: false }}
/>
</Stack.Navigator>
);
}
function SettingsStack() {
return (
<Stack.Navigator>
<Stack.Screen
name="Settings"
component={SettingsScreen}
options={{ headerShown: false }}
/>
</Stack.Navigator>
);
}
function App() {
function App() {
const [Acount, setAcount] = useState(0)
this.state = {
Acount: 2
};
handleacount = (data) => {
this.state = {
Acount: 9
};
alert(this.state.acount)
}
return (
<NavigationContainer>
<Tab.Navigator
tabBarOptions={{
activeTintColor: '#b08cf3',
inactiveTintColor: 'black',
}}>
<Tab.Screen
name="HomeStack"
component={HomeScreen}
options={{
tabBarLabel: 'Home',
tabBarIcon: ({ color, size }) => (
<MaterialCommunityIcons name="home" color={color} size={30} />
),
}}
/>
<Tab.Screen
name="SearchStack"
component={SearchScreen}
options={{
tabBarLabel: 'Search',
tabBarIcon: ({ color, size }) => (
<MaterialCommunityIcons
name="account-search"
color={color}
size={30}
/>
),
}}
/>
<Tab.Screen
name="NotificationsStack"
component={NotificationsScreen}
options={{
tabBarBadge: 5,
tabBarLabel: 'Notifications',
tabBarIcon: ({ color, size }) => (
<MaterialCommunityIcons name="bell" color={color} size={30} />
),
}}
/>
<Tab.Screen
name="MapStack"
component={MapScreen}
options={{
tabBarLabel: 'Map',
tabBarIcon: ({ focused, color, size }) => {
return (
<View>
<MaterialCommunityIcons name="map-marker" size={30} color='rgb(68,68,68)' style={{ marginTop:0 }}/>
<View style={{position:'absolute', bottom:32, left:-38 }}>
<IconBadge
MainElement={
<View>
</View>
}
BadgeElement={
// here your text in badge icon
<Text style={{fontWeight: 900,fontFamily: "sans-serif-medium",
fontSize: 14,color:'#FFFFFF', Top:10 }}>{ this.state.acount }</Text>
}
IconBadgeStyle={
{width:20,
height:20,
borderWidth: 2,
borderColor: "#b5b5b5",
backgroundColor: '#ff8a8a'}
}
/></View>
</View>
);
},
}}
/>
<Tab.Screen
name="SettingsStack"
component={SettingsScreen}
options={{
tabBarLabel: 'Account',
tabBarIcon: ({ color, size }) => (
<MaterialCommunityIcons
name="account"
color={color}
size={30}
/>
),
}}
/>
</Tab.Navigator>
</NavigationContainer>
);
}
const styles = StyleSheet.create({
container: {
flex: 1
}
});
export default App;
State belongs to the component so you should move it inside the App component like this
function App() {
const [account, setAccount] = useState(0)
...
}
But how do you call the setAccount from another page you wonder and there you need to have a look into React Context or Redux.
Context: https://reactjs.org/docs/context.html
Redux: https://redux.js.org/
I sorted it by place this in another page:
<Button
onPress={() => {increment(2)}} title="Click Me"
/>
Then in the function App I added
// State: a counter value
const [counter, setCounter] = useState(0)
increment = (data) => {
setCounter(data)
}
Not entirely sure how or why this works though?

React Native Top Area View

I'm new to React Native and I have a very simple first page that I'm testing out. My only thing I'm having a hard time understanding is where there is a Title view at the top area. Here's what my app currently looks like https://i.stack.imgur.com/H7vbO.png As you can see, there's that huge white space that has "Home" in it. I'm trying to get rid of it completely and just have the my background color throughout the whole thing. My only problem is that I don't even know where that is coming from. Here is my code and thank you.
This is my HomeScreen
import React from "react";
import { StyleSheet, Text, SafeAreaView, Platform } from "react-native";
import { StatusBar } from "expo-status-bar";
const HomeScreen = ({}) => {
return (
<SafeAreaView style={styles.container}>
<Text style={{ color: "white" }}>Home Screen</Text>
</SafeAreaView>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: "#4B4B4B",
alignItems: "center",
paddingTop: Platform.OS === "android" ? StatusBar.currentHeight : 0,
},
});
export default HomeScreen;
This is my App.js
import React from "react";
import { NavigationContainer } from "#react-navigation/native";
import { createNativeStackNavigator } from "#react-navigation/native-stack";
import MainTabScreen from "./screens/MainTabScreen";
const Stack = createNativeStackNavigator();
const App = () => {
return (
<NavigationContainer>
<MainTabScreen />
</NavigationContainer>
);
};
export default App;
Here is my MainTabScreen
import React from "react";
import { createBottomTabNavigator } from "#react-navigation/bottom-tabs";
import Icon from "react-native-vector-icons/Ionicons";
import HomeScreen from "./HomeScreen";
import SearchScreen from "./SearchScreen";
import InboxScreen from "./InboxScreen";
import AccoutScreen from "./AccountScreen";
const Tab = createBottomTabNavigator();
const MainTabScreen = () => {
return (
<Tab.Navigator initialRouteName="Home" activeColor="#000000">
<Tab.Screen
name="Home"
component={HomeScreen}
options={{
tabBarIcon: ({ color }) => (
<Icon name="ios-home" color={color} size={26} />
),
}}
/>
<Tab.Screen
name="Search"
component={SearchScreen}
options={{
tabBarIcon: ({ color }) => (
<Icon name="ios-search" color={color} size={26} />
),
}}
/>
<Tab.Screen
name="Inbox"
component={InboxScreen}
options={{
tabBarIcon: ({ color }) => (
<Icon name="ios-chatbox" color={color} size={26} />
),
}}
/>
<Tab.Screen
name="Account"
component={AccoutScreen}
options={{
tabBarIcon: ({ color }) => (
<Icon name="ios-person" color={color} size={26} />
),
}}
/>
</Tab.Navigator>
);
};
export default MainTabScreen;
P.S.: I already tried changing SafeAreaView to just View, and I also try removing the padding top
That view is actually the header of the navigator. Thus, to remove it, on your main navigator, set headerShown: false.
In your mainTabScreen;
<Tab.Navigator screenOptions={{headerShown: false}} initialRouteName="Home" activeColor="#000000">
...
Rest will be same.
Bottom tab accepts header related options in options property of Navigator Screens and screenOptions property in The Navigator Component
e.g
const MainTabScreen = () => {
return (
<Tab.Navigator
initialRouteName="Home"
activeColor="#000000"
// To remove header from all screens,
// screenOptions={{ headerShown: false }}
>
<Tab.Screen
name="Home"
component={Home}
options={{
tabBarIcon: ({ color }) => (
<Icon name="ios-home" color={color} size={26} />
),
// Update Header Title
// headerTitle: 'NOT A HOME',
}}
/>
<Tab.Screen
name="Search"
component={Home}
options={{
tabBarIcon: ({ color }) => (
<Icon name="ios-search" color={color} size={26} />
),
}}
/>
</Tab.Navigator>
);
};
You can read about all header related options in - https://reactnavigation.org/docs/elements#header

undefined is not an object (evaluating 'object.keys(routeConfigs)') [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 2 years ago.
Improve this question
This is the error I am receiving. Please tell me what file you need to see. Apologies if the problem is not to the point, I am a noob here.
First image shows the error
Below is the file which calls for stack navigator.
This file calls for stacknavigator
If you need anything else, please tell me, I'll add it in further edits
import React from "react";
import { Easing, Animated, Dimensions } from "react-native";
//import {createAppContainer} from 'react-navigation';
import {createStackNavigator} from 'react-navigation-stack';
import { createDrawerNavigator,DrawerItems} from 'react-navigation-drawer';
//import { createBottomTabNavigator } from 'react-navigation-bottom-tabs';
import { Block } from "galio-framework";
// screens
import HomeActivity from '../components/HomeActivity.js';
import ProfileActivity from '../components/ProfileActivity.js';
import Results from '../components/Results.js';
// import HomeActivity from "../screens/Home";
// import Onboarding from "../screens/Onboarding";
import Pro from "../components/Pro";
import Profile from "../components/Profile";
// import Register from "../screens/Register";
// import Elements from "../screens/Elements";
// import Articles from "../screens/Articles";
// drawer
import CustomDrawerContent from "./Menu";
// header for screens
import Icon from "../components/Icon";
import Header from "../components/Header";
import { argonTheme, tabs } from "../constants";
const { width } = Dimensions.get("screen");
const Stack = createStackNavigator();
const Drawer = createDrawerNavigator();
//const Tab = createBottomTabNavigator();
function ElementsStack(props) {
return (
<Stack.Navigator mode="card" headerMode="screen">
<Stack.Screen
name="Elements"
component={Profile}
options={{
header: ({ navigation, scene }) => (
<Header title="Elements" navigation={navigation} scene={scene} />
),
cardStyle: { backgroundColor: "#F8F9FE" }
}}
/>
<Stack.Screen
name="Pro"
component={Pro}
options={{
header: ({ navigation, scene }) => (
<Header
title=""
back
white
transparent
navigation={navigation}
scene={scene}
/>
),
headerTransparent: true
}}
/>
</Stack.Navigator>
);
}
function ArticlesStack(props) {
return (
<Stack.Navigator mode="card" headerMode="screen">
<Stack.Screen
name="Articles"
component={Articles}
options={{
header: ({ navigation, scene }) => (
<Header title="Articles" navigation={navigation} scene={scene} />
),
cardStyle: { backgroundColor: "#F8F9FE" }
}}
/>
<Stack.Screen
name="Pro"
component={Pro}
options={{
header: ({ navigation, scene }) => (
<Header
title=""
back
white
transparent
navigation={navigation}
scene={scene}
/>
),
headerTransparent: true
}}
/>
</Stack.Navigator>
);
}
function ProfileStack(props) {
return (
<Stack.Navigator initialRouteName="Profile" mode="card" headerMode="screen">
<Stack.Screen
name="Profile"
component={ProfileActivity}
options={{
header: ({ navigation, scene }) => (
<Header
transparent
white
title="Profile"
navigation={navigation}
scene={scene}
/>
),
cardStyle: { backgroundColor: "#FFFFFF" },
headerTransparent: true
}}
/>
<Stack.Screen
name="Pro"
component={Pro}
options={{
header: ({ navigation, scene }) => (
<Header
title=""
back
white
transparent
navigation={navigation}
scene={scene}
/>
),
headerTransparent: true
}}
/>
</Stack.Navigator>
);
}
function HomeStack(props) {
return (
<Stack.Navigator mode="card" headerMode="screen">
<Stack.Screen
name="Home"
component={HomeActivity}
options={{
header: ({ navigation, scene }) => (
<Header
title="Home"
search
options
navigation={navigation}
scene={scene}
/>
),
cardStyle: { backgroundColor: "#F8F9FE" }
}}
/>
<Stack.Screen
name="Pro"
component={Pro}
options={{
header: ({ navigation, scene }) => (
<Header
title=""
back
white
transparent
navigation={navigation}
scene={scene}
/>
),
headerTransparent: true
}}
/>
</Stack.Navigator>
);
}
export default function OnboardingStack(props) {
return (
<Stack.Navigator mode="card" headerMode="none">
<Stack.Screen
name="Jobs"
component={Results}
option={{
headerTransparent: true
}}
/>
<Stack.Screen name="App" component={AppStack} />
</Stack.Navigator>
);
}
function AppStack(props) {
return (
<Drawer.Navigator
style={{ flex: 1 }}
drawerContent={props => <CustomDrawerContent {...props} />}
drawerStyle={{
backgroundColor: "white",
width: width * 0.8
}}
drawerContentOptions={{
activeTintcolor: "white",
inactiveTintColor: "#000",
activeBackgroundColor: "transparent",
itemStyle: {
width: width * 0.75,
backgroundColor: "transparent",
paddingVertical: 16,
paddingHorizonal: 12,
justifyContent: "center",
alignContent: "center",
alignItems: "center",
overflow: "hidden"
},
labelStyle: {
fontSize: 18,
marginLeft: 12,
fontWeight: "normal"
}
}}
initialRouteName="Home"
>
<Drawer.Screen name="Home" component={HomeStack} />
<Drawer.Screen name="Profile" component={ProfileStack} />
<Drawer.Screen name="Results" component={OnboardingStack} />
<Drawer.Screen name="Elements" component={ElementsStack} />
{/* <Drawer.Screen name="Articles" component={ArticlesStack} /> */}
</Drawer.Navigator>
);
}
So based on the error i would say that validateRouteConfigMap.js is getting an object(routeConfigs) that you've not yet defined or passed in as undefined or you have not set a default value for. Remember Object.keys(ARRAY_OR_OBJECT_VARIABLE) requires a variable of object type (besides null)