I am new to react native and am trying to create a tabbar using createBottomTabNavigator. I would like each tab to have its own icon.
I have followed the following tutorial which uses FontAwesome to display the tab icon.
Tutorial
When I run my app in the iso simulator the tabs display but the icons don't.
Here is my code
import { createStackNavigator } from 'react-navigation-stack';
import { createAppContainer } from 'react-navigation';
import { createBottomTabNavigator } from 'react-navigation-tabs';
import Icon from "react-native-vector-icons/FontAwesome5";
import HomeScreen from './HomeScreen';
import SecondActivity from './second';
const TabNavigator = createBottomTabNavigator({
Home: { screen: HomeScreen,
defaultNavigationOptions: {
tabBarIcon: ({tintColor}) =>
<Icon name="home" size={25} color={tintColor} />
}
},
Events: { screen: SecondActivity,
defaultNavigationOptions: {
tabBarIcon: ({tintColor}) =>
<Icon name="chart-bar" size={25} color={tintColor} />
}
}
}
);
const MyStack = createStackNavigator({
Tabs: {
screen: TabNavigator
},
Home: {
screen: HomeScreen
},
Events: {
screen: SecondActivity
}
},
{
initialRouteName: 'Tabs',
}
);
export default createAppContainer(MyStack);
How do I get the icons to display?
I have a solution for you that is a bit different that what you did in there .. so
const config = Platform.select({
web: { headerMode: "screen" },
default: {}
})
const HomeStack = createStackNavigator(
{
Home: HomeScreen
},
config
)
HomeStack.navigationOptions = {
tabBarIcon: ({ focused }) => (
<TabBarIcon
focused={focused}
name={Platform.OS === "ios" ? "ios-calendar" : "md-calendar"}
/>
)
}
HomeStack.path = ""
and them you can do like this in createBottomTabNavigator
const tabNavigator = createBottomTabNavigator(
{
HomeStack,
},
{
activeColor: '#000'
}
// You can import Ionicons from #expo/vector-icons if you use Expo or
// react-native-vector-icons/Ionicons otherwise.
import Ionicons from 'react-native-vector-icons/Ionicons';
import { createAppContainer } from 'react-navigation';
import { createBottomTabNavigator } from 'react-navigation-tabs';
export default createBottomTabNavigator(
{
Home: HomeScreen,
Settings: SettingsScreen,
},
{
defaultNavigationOptions: ({ navigation }) => ({
tabBarIcon: ({ focused, horizontal, tintColor }) => {
const { routeName } = navigation.state;
let IconComponent = Ionicons;
let iconName;
if (routeName === 'Home') {
iconName = focused
? 'ios-information-circle'
: 'ios-information-circle-outline';
// Sometimes we want to add badges to some icons.
// You can check the implementation below.
IconComponent = HomeIconWithBadge;
} else if (routeName === 'Settings') {
iconName = focused ? 'ios-list-box' : 'ios-list';
}
// You can return any component that you like here!
return <IconComponent name={iconName} size={25} color={tintColor} />;
},
}),
tabBarOptions: {
activeTintColor: 'tomato',
inactiveTintColor: 'gray',
},
}
);
Link : https://snack.expo.io/#react-navigation/basic-tabs-v3
Link : https://reactnavigation.org/docs/en/tab-based-navigation.html
Related
Current code
App.js
import React from 'react';
import {NavigationContainer} from '#react-navigation/native';
import {createStackNavigator} from '#react-navigation/stack';
import { Icon } from 'react-native-elements';
import HomeScreen from 'app/src/screens/home/Index';
import DetailScreen from 'app/src/screens/home/Detail';
import MypageScreen from 'app/src/screens/mypage/Index';
import InitialScreen from 'app/src/screens/authentication/Initial';
const Home = {
screen: HomeScreen,
navigationOptions: ({ navigation }) => {
return {
title: 'Home',
};
},
};
const Detail = {
screen: DetailScreen,
navigationOptions: ({ navigation }) => {
return {
title: 'Detail',
};
},
};
const Mypage = {
screen: MypageScreen,
navigationOptions: ({ navigation }) => {
return {
title: 'MyPage',
};
},
};
const Initial = {
screen: InitialScreen,
navigationOptions: ({ navigation }) => {
return {
title: 'Initial',
};
},
}
const HomeStack = createStackNavigator(
{
Home,
Detail,
},
{
initialRouteName: 'Home',
navigationOptions: {
tabBarIcon: <Icon name="home" />,
},
}
);
const MypageStack = createStackNavigator(
{
Mypage,
},
{
initialRouteName: 'Mypage',
navigationOptions: {
tabBarIcon: <Icon name="person" />,
},
}
);
const postLoginNavigator = createBottomTabNavigator({
Home: HomeStack,
Mypage: MypageStack,
});
const AppNavigator = createStackNavigator({
Initial,
PostLogin: postLoginNavigator
},{
mode: 'modal',
headerMode: 'none',
initialRouteName: 'Initial'
})
const AppContainer = createAppContainer(AppNavigator);
export default class App extends React.Component {
render() {
return (
<AppContainer />
);
}
}
What I want to do
I wanna make tabs in bottom using createBottomTabNavigator.
Home and My Page tabs.
Error that I'm facing
Error: Creating a navigator doesn't take an argument. Maybe you are trying to use React Navigation 4 API with React Navigation 5?
ps
I'm using
"#react-navigation/native": "^5.2.3",
"#react-navigation/stack": "^5.2.8",
"#react-navigation/bottom-tabs": "^5.0.6",
I would appreciate it if you could give me any advices.
const MyTabs = () => {
return(
<Tab.Navigator>
<Tab.Screen name="Home" component={HomeScreen} />
<Tab.Screen name="Mypage" component={MypageScreen} />
</Tab.Navigator>);
}
Can you try this? I think I missed the return statement
Add the bottomTabNavigator inside a StackNavigator. In future, if you are adding more screens you can add it to the stack
import React from 'react';
import {NavigationContainer} from '#react-navigation/native';
import {createStackNavigator} from '#react-navigation/stack';
import { createBottomTabNavigator } from 'react-navigation-tabs';
import { Icon } from 'react-native-elements';
import HomeScreen from 'app/src/screens/home/Index';
import MypageScreen from 'app/src/screens/mypage/Index';
const Stack = createStackNavigator();
const Tab = createBottomTabNavigator();
const MyTabs = () => {
<Tab.Navigator>
<Tab.Screen name="Home" component={HomeScreen} />
<Tab.Screen name="Mypage" component={MypageScreen} />
</Tab.Navigator>
}
const AuthStack = () => (
<Stack.Navigator>
<Stack.Screen name="Tabs" component={MyTabs} />
</Stack.Navigator>
);
const AuthenticationNavigator = () => (
<NavigationContainer>
<AuthStack />
</NavigationContainer>
);
export default AuthenticationNavigator;
I have just implemented an Auth stack and having an issue with my TabNavigator - when I click my second "Favourites" tab which is in my tab navigator and referenced the MainNavigator within my switch I get the message There is no route named 'Favourites' in the navigator with the key 'Dashboard. Must be one of: 'Dashboard, Admin'. This was working perfectly fine before I introduced switch navigator and had MainNavigator in my appContainer. Any clues?
import React from "react";
import { Platform, Text } from "react-native";
import { createAppContainer, createSwitchNavigator} from "react-navigation";
import { createStackNavigator } from "react-navigation-stack";
import { createDrawerNavigator } from "react-navigation-drawer";
import { createBottomTabNavigator } from "react-navigation-tabs";
import { createMaterialBottomTabNavigator } from "react-navigation-material-bottom-tabs";
//Components
import DashboardScreen from "../screens/DashboardScreen";
import MapScreen from "../screens/MapScreen";
import VenueOverviewScreen from "../screens/VenueOverviewScreen";
import VenueDetailScreen from "../screens/VenueDetailScreen";
import QRCodeScanScreen from "../screens/QRCodeScanScreen";
import FavouritesScreen from "../screens/FavouritesScreen";
import AdminVenueScreen from "../screens/admin/AdminVenueScreen";
import AdminUserListScreen from "../screens/admin/AdminUserListScreen";
import AdminUserDetailScreen from "../screens/admin/AdminUserDetailScreen";
import AuthScreen from "../screens/auth/AuthScreen";
//Misc
import Colors from "../constants/Colors";
import { Ionicons } from "#expo/vector-icons";
//Default Nav
const defaultNavOptions = {
headerStyle: {
backgroundColor: Colors.brownPrimaryDark
},
headerTitleStyle: {
fontFamily: "roboto-regular"
},
headerTintColor: "white"
};
//Default Admin
const defaultAdminNavOptions = {
headerStyle: {
backgroundColor: Colors.greenPrimary
},
headerTitleStyle: {
fontFamily: "roboto-regular"
},
headerTintColor: "white"
};
//Main Stack
const HomeNavigator = createStackNavigator(
{
Dashboard: DashboardScreen,
Map: MapScreen,
Venues: VenueOverviewScreen,
VenueDetail: VenueDetailScreen,
},
{
defaultNavigationOptions: defaultNavOptions
}
);
//Fav Stack
const FavNavigator = createStackNavigator(
{
Favourites: FavouritesScreen
},
{
defaultNavigationOptions: defaultNavOptions
}
);
//AdminStack
const AdminNavigator = createStackNavigator(
{
Admin: AdminVenueScreen,
AdminUserList: AdminUserListScreen,
AdminUserDetail: AdminUserDetailScreen,
QRCodeScan: QRCodeScanScreen
},
{
defaultNavigationOptions: defaultAdminNavOptions
}
);
//Tab Config
const tabScreenConfig = {
Home: {
screen: HomeNavigator,
navigationOptions: {
tabBarLabel:
Platform.OS === "android" ? (
<Text style={{ fontFamily: "roboto-regular" }}>Dashboard</Text>
) : (
"Dashboard"
),
tabBarIcon: tabInfo => {
return <Ionicons name="ios-home" size={23} color={tabInfo.tintColor} />;
},
//tabBarColor: Colors.greyDark, //only shifting effect
}
},
Favourites: {
screen: FavNavigator,
navigationOptions: {
tabBarLabel:
Platform.OS === "android" ? (
<Text style={{ fontFamily: "roboto-regular" }}>Favourties</Text>
) : (
"Favourties"
),
tabBarIcon: tabInfo => {
return <Ionicons name="ios-star" size={23} color={tabInfo.tintColor} />;
},
//tabBarColor: Colors.greenPrimary //only shifting effect onPress
}
}
};
const TabNavigator =
Platform.OS === "android"
? createMaterialBottomTabNavigator(tabScreenConfig, {
activeTintColor: Colors.brownSecondaryLight,
shifting: true,
barStyle: { backgroundColor: '#eee' },
activeColor: Colors.greyDarker,
inactiveColor:'#ccc',
})
: createBottomTabNavigator(tabScreenConfig, {
tabBarOptions: {
labelStyle: {
fontFamily: "roboto-regular",
fontSize: 15
},
activeTintColor: Colors.greenPrimary,
}
});
const MainNavigator = createDrawerNavigator(
{
Dashboard: {
screen: TabNavigator,
navigationOptions: {
drawerLabel: "Dashboard",
drawerIcon: drawerConfig => (
<Ionicons
name="ios-home"
size={23}
color={drawerConfig.tintColor}
/>
)
}
},
Admin: {
screen: AdminNavigator,
navigationOptions: {
drawerLabel: "Admin",
drawerIcon: drawerConfig => (
<Ionicons
name="ios-lock"
size={23}
color={drawerConfig.tintColor}
/>
)
}
}
},
{
contentOptions: {
activeTintColor: Colors.greenPrimary,
itemsContainerStyle: {
marginVertical: 0
},
iconContainerStyle: {
opacity: 1
}
},
drawerPosition: "right",
}
);
const AuthNavigator = createStackNavigator(
{
Auth: AuthScreen
},
{
headerMode: "none",
navigationOptions: {
headerVisible: false
}
}
);
const MainAuthNavigator = createSwitchNavigator({
Auth: AuthNavigator,
Dashboard: MainNavigator, //User
});
export default createAppContainer(MainAuthNavigator);
try changing the key dashboard. You use it everywhere (three times)! just try Dashboard1, Dashboard2, etc
const MainAuthNavigator = createSwitchNavigator({
Auth: AuthNavigator,
Dashboard2: MainNavigator,
});
I'm adding in the react-navigation header a drawerMenuButton to open the Drawer Menu.
The icon appears normally but when pressed returns the error quoted.
import React from 'react';
import { View, Dimensions } from 'react-native';
import { Button, Icon } from 'native-base';
import { createAppContainer, createStackNavigator, createDrawerNavigator } from 'react-navigation';
...
const DrawerConfig = {
drawerWidth: Dimensions.get('window').width * 0.75,
contentComponent: ({ navigation }) => {
return(<MenuDrawer navigation={navigation} />)
}
}
const HomeNavigator = createStackNavigator ({
...
}, {
defaultNavigationOptions: ({ navigation }) => {
return {
headerTitleStyle: {
fontWeight: 'bold'
},
headerLeft: (
<Button transparent onPress={() => this.props.navigation.toggleDrawer()}>
<Icon name='menu' style={{color: '#FFF'}} />
</Button>
),
headerRight: (
<HomeIcon navigation={navigation} />
),
headerStyle: {
backgroundColor: '#b80003'
},
headerTintColor: '#FFF'
}
}
});
const DrawerNavigator = createDrawerNavigator (
{
'Principal': {
screen: HomeNavigator
},
'Sobre o Aplicativo': {
screen: InformationApp
},
'Sobre os Responsáveis': {
screen: Team
},
'Sobre o Projeto': {
screen: Project
},
'Política e Termos': {
screen: Policy
}
},
DrawerConfig
);
const AppDrawerContainer = createAppContainer(DrawerNavigator);
export default AppDrawerContainer;
It is important to note that for screens belonging to const DrawerNavigator = createDrawerNavigator I am using the same code above to render drawerMenuButton and it is working normally, the error occurs only on const screens HomeNavigator = createStackNavigator.
Change your code like this
onPress={() => navigation.toggleDrawer()}>
I am using nested navigation drawer > tab > stack navigators.
navigators are working but when i tap on tab item its throwing the following error
undefined is not an object (evaluating '_ref4.route')
_getOnPress
TabView.js:110:44
_handleOnPress
TabBarTop.js:127:31 onPress
TabBar.js:466:33
_callTimer
JSTimers.js:156:15 callTimers
JSTimers.js:411:17
__callFunction
MessageQueue.js:302:47
MessageQueue.js:116:26
__guard
MessageQueue.js:265:6 callFunctionReturnFlushedQueue
MessageQueue.js:115:17
I am stuck here i tried many thing but no success
here is my code
DrawerNav.js
import React, { Component } from 'react';
import { DrawerNavigator} from 'react-navigation';
import Icon from "react-native-vector-icons/FontAwesome";
import stackNav from './stackNav';
const Drawer = DrawerNavigator({
DrawerItem1: {
screen: stackNav,
navigationOptions: {
drawerLabel: "Drawer Item 1",
drawerIcon: ({ tintColor }) => <Icon name="rocket" size={24} />
},
},
DrawerItem2: {
screen: stackNav,
navigationOptions: {
drawerLabel: "Drawer Item 2",
drawerIcon: ({ tintColor }) => <Icon name="rocket" size={24} />
},
}
});
export default Drawer;
TabNav.js
import React, { Component } from 'react';
import { TabNavigator, TabView } from 'react-navigation'
import Icon from "react-native-vector-icons/FontAwesome";
import MainScreen from './screens/MainScreen';
const tabNav = TabNavigator({
TabItem1: {
screen: MainScreen,
navigationOptions: {
tabBarLabel:"Tab One",
tabBarIcon: ({ tintColor }) => <Icon name={"glass"} size={30} color={tintColor} />
}
},
TabItem2: {
screen: MainScreen,
navigationOptions: {
tabBarLabel:"Tab Two",
tabBarIcon: ({ tintColor }) => <Icon name={"glass"} size={30} color={tintColor} />
}
},
TabItem3: {
screen: MainScreen,
navigationOptions: {
tabBarLabel:"Tab Three",
tabBarIcon: ({ tintColor }) => <Icon name={"glass"} size={30} color={tintColor} />
}
}
///... add more tabs here
}, {
tabBarPosition: 'bottom',
tabBarOptions: {
activeTintColor: '#222'
},
});
export default tabNav;
stackNav.js
import React, { Component } from 'react';
import { TouchableOpacity } from 'react-native';
import { StackNavigator} from 'react-navigation'
import IOSIcon from "react-native-vector-icons/Ionicons";
import DetailScreen from './screens/DetailScreen';
import MainScreen from './screens/MainScreen';
import tabNav from './tabNav'
const stackNav = StackNavigator({
Main: {
screen: tabNav,
navigationOptions:({navigation}) => ({
title: "Main",
headerLeft:(
<TouchableOpacity onPress={() => navigation.navigate("DrawerOpen")}>
<IOSIcon name="ios-menu" size={30} />
</TouchableOpacity>
),
headerStyle: { paddingRight: 10, paddingLeft: 10 },
})
},
Detail: {
screen: DetailScreen,
navigationOptions: (props) => ({
title: "Detail",
})
}
})
export default stackNav;
I have the same error with TabNavigator.
I also have executed the official react-navigation example (https://github.com/react-community/react-navigation/blob/master/examples/NavigationPlayground/js/SimpleTabs.js) with no success (same error).
My guess is that this is a bug of latest versions of Expo/React Native.
What versions are you using?
I'm using:
"dependencies": {
"expo": "^22.0.2",
"react": "16.0.0-beta.5",
"react-native": "^0.49.5",
"react-navigation": "^1.0.0-beta.20"
}
Confirmed: ejecting from Create React Native App solves the problem.
So, it seems to be a bug on Create React Native App or Expo.
I adding image of screen, this work in part of screen.
The Contacts screen need to be main page and not screen1 but its didn't work if i replace between them.
I adding the code, in 'LogedInNavigator' have there TabNavigator and DrawerNavigator - the 'Contants' page initializing from TabNavigator and part two - Screen1 with the side menu it's from DrawerNavigator - maybe it's doing the problem?
LogedInNavigator.js
import.......
styles......
const LoggedInNavigator = TabNavigator(
{
Contacts: {screen: ContactScreen,},
Chat: {screen: ChatScreen,},
Dashbaord: {screen: DashbaordScreen,},
Profile: {screen: ProfileScreen,},
Search: {screen: SearchScreen,},
},
{
initialRouteName: "Contacts",
tabBarPosition: "bottom",
tabBarOptions: {
showIcon: true,
activeTintColor: 'white',
}
}
);
export default () => <LoggedInNavigator onNavigationStateChange={null} />
export const Drawer = DrawerNavigator ({
Home:{
screen: Screen1,
navigationOptions: {
drawer:{
label: 'Home',
},
}
},
Camera: {
screen: Screen2,
navigationOptions: {
drawer:{
label: 'Camera',
},
}
},
})
Contants.js
class Contacts extends Component {
componentDidMount() {
// TBD loggedin should come from login process and removed from here
const { loggedIn, getContacts } = this.props;
loggedIn(1);
getContacts();
}
render() {
const Router = createRouter( () => ({})); //IDAN
const { navigation, avatar, contacts } = this.props;
return (
<NavigationProvider router={Router}>
<View style={{flex:1}}>
<ContactView
navigation={navigation}
avatar={avatar}
contacts={contacts}
/>
<Drawer />
</View>
</NavigationProvider>
);
}
}
const mapStateToProps = (state) => {
return (
{
avatar: state.user.user.avatar,
contacts: state.contacts.contacts,
}
);
};
export default connect(mapStateToProps, { loggedIn, getContacts })(Contacts);
Help me please..
After a while, i want to answer on my own question (with react-navigation v2)
everything inside <RootNavigator/>
const RootNavigator= createDrawerNavigator({ Tabs }, {
contentComponent: SideMenu,
drawerWidth: Dimensions.get('window').width * .75,
})
SideMenu:
class SideMenu extends Component {
render() {
return ( //...your side menu view )
}
}
Tab:
export default createBottomTabNavigator({
Menu: {
screen: HomeStack,
navigationOptions: {
title: 'תפריט',
tabBarIcon: ({ focused, tintColor }) => {
return <Icon name={'home'} size={20} color={tintColor} />;
},
}
},
Dashboard: {
screen: DashboardStack,
navigationOptions: {
title: 'בית',
tabBarOnPress: ({ navigation, defaultHandler }) => handleTabPress(navigation, defaultHandler),
tabBarIcon: ({ focused, tintColor }) => {
return <Icon name={'dashboard'} size={20} color={'green'} />;
},
}
},
QuickView: {
screen: QuickNav,
navigationOptions: {
title: 'מבט מהיר',
tabBarIcon: ({ focused, tintColor }) => {
return <Icon name={'short-list'} size={20} color={tintColor} />;
},
},
},
Chat: {
screen: Chat,
navigationOptions: {
title: "צ'אט",
tabBarIcon: ({ focused, tintColor }) => {
return <Icon name={'chat'} size={20} color={tintColor} />;
},
},
},
},
{
initialRouteName: 'Dashboard',
tabBarOptions: {
activeTintColor: 'green',
labelStyle: {
fontSize: 16,
marginBottom: 3,
},
},
},
)
For v5 onwards you can use drawer style
import deviceInfoModule from 'react-native-device-info';
<Drawer.Navigator
drawerStyle={{
width: deviceInfoModule.isTablet()
? Dimensions.get('window').width * 0.55
: Dimensions.get('window').width * 0.7,
}}
You can set the drawer width using Dimensions width. See the docs here
https://reactnavigation.org/docs/navigators/drawer
import { Dimensions } from 'react-native';
...
const { width } = Dimensions.get('screen');
...
export const Drawer = DrawerNavigator (
{
Home:{
screen: Screen1,
navigationOptions: {
drawer:{
label: 'Home',
},
}
},
Camera: {
screen: Screen2,
navigationOptions: {
drawer:{
label: 'Camera',
},
}
},
},
{
drawerWidth: width
});
In react-navigation version 6, you can use the drawerStyle in the screenOptions prop in the Drawer.Navigator component to change the width and add styles. This applies the applied style to all screens in the navigator.
<Drawer.Navigator
screenOptions: {{
drawerStyle: {
width: 240
}
}}
>
If you want the drawer to cover the entire screen, then import Dimensions from the react-native library and use Dimensions.get('window').width
import { Dimensions } from 'react-native'
<Drawer.Navigator
screenOptions: {{
drawerStyle: {
width: Dimensions.get('window').width
}
}}
>
Refer to react-navigation drawer for more.