I am trying to build a bottom navigation bar, everything works but the navigation bar does not show up. I am kinda new to react native too. I feel like the problem is the export default as it was not taking the object as the App registry.
The other files work too, like there is no error but the navigation bar does not show up
import React, { Component } from "react";
import { AppRegistry, Text, View, StyleSheet } from "react-native";
import Icon from "react-native-vector-icons/FontAwesome";
import { NavigationComponent } from "react-native-material-bottom-
navigation";
import { TabNavigator } from "react-navigation";
import Home from "./app/components/home.js";
import BackgroundImage from "./app/components/BackgroundImage.js";
import FadeAnimation from
"./app/components/animations/fadeAnimation.js";
class HomeScreen extends React.Component {
static navigationOptions = {
tabBarLabel: "Home",
tabBarIcon: () => <Icon size={24} color="white" name="home" />
};
render() {
return (
<BackgroundImage>
<Home />
</BackgroundImage>
);
}
}
class Announcements extends React.Component {
static navigationOptions = {
tabBarLabel: "Announcements",
tabBarIcon: () => <Icon size={24} color="white" name="bullhorn" />
};
render() {
return (
<View>
<Text>This is announcement page</Text>
</View>
);
}
}
class Calendar extends React.Component {
static navigationOptions = {
tabBarLabel: "Calendar",
tabBarIcon: () => <Icon size={24} color="white" name="calendar" />
};
render() {
return (
<View>
<Text>This is announcement page</Text>
</View>
);
}
}
class Contact extends React.Component {
static navigationOptions = {
tabBarLabel: "Contact",
tabBarIcon: () => <Icon size={24} color="white" name="comments" />
};
render() {
return (
<View>
<Text>This is announcement page</Text>
</View>
);
}
}
const MyApp = TabNavigator(
{
HomeScreen: { screen: HomeScreen },
Announcements: { screen: Announcements },
Calendar: { screen: Calendar },
Contact: { screen: Contact }
},
{
tabBarComponent: NavigationComponent,
tabBarPosition: "bottom",
tabBarOptions: {
bottomNavigationOptions: {
labelColor: "white",
rippleColor: "white",
tabs: {
HomeScreen: {
barBackgroundColor: "#3C2538"
},
Announcements: {
barBackgroundColor: "#388E3C"
},
Calendar: {
barBackgroundColor: "#E64A19",
labelColor: "#434343",
activeLabelColor: "#212121",
activeIcon: <Icon size={24} color="#212121" name="calendar" />
},
Contact: {
barBackgroundColor: "#a0c4ff"
}
}
}
}
}
);
export default MyApp;
AppRegistry.registerComponent("MyApp", () => MyApp);
Maybe my case may help you, so in App.js create the bottom tab navigator, just import the createBottomTabNavigator, then import some screen that you want to put on my bottom tab navigation, this is the example of my code :
import { createBottomTabNavigator, createAppContainer } from 'react-navigation';
import Users from './Users';
import Vehicles from './Vehicles';
import Home from './Home';
import MyAccount from './MyAccount';
export default class Dashboard extends Component {
static navigationOptions = {
header: null,
};
render() {
return (
<AppContainer/>
);
}
}
const TabScreens = createBottomTabNavigator({
Home:{
screen: Home
},
Users:{
screen: Users,
},
Vehicles:{
screen: Vehicles
},
MyAccount:{
screen: MyAccount
},
},{
tabBarOptions:{
labelStyle: {
fontSize: 12,
marginBottom:10,
},
style:{
elevation:5
}
}
})
const AppContainer = createAppContainer(TabScreens);
Hope it will help you
Related
I am creating a very simple tab navigation with two screens. I want to show a header on top of each screen. I am running the following code, but I don't see any header. The header just does not appear.
I am using react-navigation#3.11.1, I tried reverting back to 3.10.0 and even 3.0.0 and still don't see the headers. So I am assuming it's not a bug in react-navigation.
Update: This is the expected behavior. See: https://github.com/react-navigation/react-navigation/issues/6149
import React, {Component} from 'react';
import { View, Text } from 'react-native';
import { createAppContainer, createBottomTabNavigator } from 'react-navigation';
class MusicScreen extends Component {
static navigationOptions = {
title: 'Musiiic',
};
render() {
return (
<View >
<Text>Music Screen</Text>
</View>
);
}
}
class MoviesScreen extends Component {
static navigationOptions = {
headerTitle: 'Movies',
};
render() {
return (
<View>
<Text>Movies Screen</Text>
</View>
);
}
}
const MainNavigation = createBottomTabNavigator({
Music : {
screen: MusicScreen,
navigationOptions: ({navigation}) => ({
title: 'Music',
headerTitle: <Text>MUSIICCCC</Text>,
})
},
Movies : {
screen: MoviesScreen,
navigationOptions: {
title: 'Movies',
},
},
},
{
headerMode: 'screen',
navigationOptions: {
headerVisible: true,
},
}
);
export default createAppContainer(MainNavigation);
Can you try like the following?
eg:
...
...
class MusicScreen extends Component {
static navigationOptions = {
title: 'MUSIICCCC',
headerStyle: {
backgroundColor: '#f4511e',
},
headerTintColor: '#fff',
headerTitleStyle: {
fontWeight: 'bold',
},
};
render() {
return (
<View >
<Text>Music Screen</Text>
</View>
);
}
}
...
...
const MainNavigation = createBottomTabNavigator({
Music : MusicScreen,
Movies MoviesScreen,
},
{
initialRouteName: 'Music',
}
);
export default createAppContainer(MainNavigation);
Try cleaning up your createBottomTabNavigator like so by removing any header data.
const MainNavigation = createBottomTabNavigator({
Music : {screen: MusicScreen},
Movies : {screen: MoviesScreen},
}
);
Add navigationOptions to each screen individually.
class MusicScreen extends Component {
static navigationOptions = {
title: 'Musiiic',
};
render() {
return (
<View >
<Text>Music Screen</Text>
</View>
);
}
}
class MoviesScreen extends Component {
static navigationOptions = {
title: 'Movies',
};
render() {
return (
<View>
<Text>Movies Screen</Text>
</View>
);
}
}
Here are some docs [https://reactnavigation.org/docs/en/headers.html]
Could you try this?
import React, {Component} from 'react';
import { View, Text } from 'react-native';
import { createAppContainer, createBottomTabNavigator } from 'react-navigation';
class MusicScreen extends Component {
render() {
return (
<View >
<Text>Music Screen</Text>
</View>
);
}
}
class MoviesScreen extends Component {
render() {
return (
<View>
<Text>Movies Screen</Text>
</View>
);
}
}
const MainNavigation = createBottomTabNavigator({
Music : {
screen: MusicScreen,
navigationOptions: {
title: "Music"
}
},
Movies : {
screen: MoviesScreen,
navigationOptions: {
title: 'Movies',
},
},
},
{
headerMode: 'screen'
}
);
export default createAppContainer(MainNavigation);
I have a bottom tab bar that locates in app.js. And I have the class where I want to hide the bottom bar. In page home.js I have 2 classes. 1st one is main (is the list of articles), the second one is for button page navigation (in this class I display articles). How I can hide bottom tab navigation in the second page (where articles are displayed). I have tried tabBarVisible: false, but this does not work. Help me, please.
Code:
// app.js
const TabNavigator = createBottomTabNavigator({
Home:{
screen:Home,
navigationOptions:{
tabBarLabel:'Главная',
tabBarIcon:({tintColor})=>(
<Icon name="ios-home" color={tintColor} size={24} />
)
}
},
Courses:{
screen:Courses,
navigationOptions:{
tabBarLabel:'Courses',
tabBarIcon:({tintColor})=>(
<Icon name="ios-school" color={tintColor} size={24} />
)
}
},
Editor:{
screen:Editor,
navigationOptions:{
tabBarLabel:'Editor',
tabBarIcon:({tintColor})=>(
<Icon name="ios-document" color={tintColor} size={24} />
)
}
},
},{
tabBarOptions:{
activeTintColor:'#db0202',
inactiveTintColor:'grey',
style:{
fontSize:3,
height:45,
backgroundColor:'white',
borderTopWidth:0,
elevation: 5
}
}
});
export default createAppContainer(TabNavigator);
// home.js
import React from 'react';
import { Font } from 'expo';
import { Button, View, Text, SafeAreaView, ActivityIndicator, ListView, StyleSheet, Image, Dimensions,
ScrollView } from 'react-native';
import { createStackNavigator, createAppContainer } from 'react-navigation'; // Version can be specified in package.json
import Icon from 'react-native-vector-icons/Ionicons'
import Courses from './Courses'
class HomeScreen extends React.Component {
static navigationOptions = {
title: 'Home',
};
const { navigate } = this.props.navigation;
return (
<SafeAreaView style={styles.MainContainer}>
<ScrollView
>
<ListView
dataSource={this.state.dataSource}
renderSeparator={this.ListViewItemSeparator}
renderRow={rowData => (
<>
<Text
onPress={() => {
/* 1. Navigate to the Details route with params */
this.props.navigation.navigate("Articles", {
otherParam: rowData.article_title,
});
}}
>
{rowData.article_title}
</Text>
</>
)}
/>
</ScrollView
>
</SafeAreaView>
);
}
}
class ArticleScreen extends React.Component {
static navigationOptions = ({ navigation, navigationOptions }) => {
const { params } = navigation.state;
return {
title: params ? params.otherParam : '',
};
};
render() {
const { params } = this.props.navigation.state;
const article_title = params ? params.otherParam : '';
return (
<Text>{article_title}</Text>
);
}
}
const RootStack = createStackNavigator(
{
Home: {
screen: HomeScreen,
},
Courses: {
screen: Courses,
navigationOptions: {
header: null,
}
},
Articles: {
screen: ArticleScreen,
},
},
{
initialRouteName: 'Home',
}
);
const AppContainer = createAppContainer(RootStack);
export default class App extends React.Component {
render() {
return <AppContainer />;
}
}
const AppContainer = createAppContainer(RootStack);
export default class App extends React.Component {
render() {
return <AppContainer />;
}
}
You have to make StackNavigator as main Navigator and TabBar as a sub navigator:
const TabBar = createBottomTabNavigator(RouteConfigs, TabNavigatorConfig);
const MainNavigator = createStackNavigator(
{
TabBar,
WelcomeScene: { screen:Scenes.WelcomeScene },
HomeScene: { screen: HomeScene }
}
Using this when you go the second screen Tabbar will hide automatically.
Can you try this?
class ArticleScreen extends React.Component {
static navigationOptions = ({ navigation }) => {
return {
title: params ? params.otherParam : '',
tabBarVisible: false
};
};
...
How about something like this. Create Tab navigator and pass it down to Stack navigator as one of the screen, when you navigate to the Articles, it will hide the tab bar...
const TabNavigator = createBottomTabNavigator({
Home: {
screen: Home,
navigationOptions: {
tabBarLabel: 'Главная',
tabBarIcon: ({ tintColor }) => (
<Icon name="ios-home" color={tintColor} size={24} />
),
},
},
Courses: {
screen: Courses,
navigationOptions: {
tabBarLabel: 'Courses',
tabBarIcon: ({ tintColor }) => (
<Icon name="ios-school" color={tintColor} size={24} />
),
},
},
Editor: {
screen: Editor,
navigationOptions: {
tabBarLabel: 'Editor',
tabBarIcon: ({ tintColor }) => (
<Icon name="ios-document" color={tintColor} size={24} />
),
},
},
}, {
tabBarOptions: {
activeTintColor: '#db0202',
inactiveTintColor: 'grey',
style: {
fontSize: 3,
height: 45,
backgroundColor: 'white',
borderTopWidth: 0,
elevation: 5,
},
},
});
const stackNavigator = createStackNavigator({
Home: {
screen: TabNavigator,
navigationOptions: {
header: null,
},
},
Articles: {
screen: ArticleScreen,
},
// add screens here which you want to hide the tab bar
});
export default createAppContainer(stackNavigator);
I followed the documentation but still getting the dreaded 500 error
I added the screens below with code, please advise on what I am missing.
the app.js page is loaded in the index.js
https://snack.expo.io/#brody182/tab-navigation-with-screen-components
react-native#.55
react-navigation#2.5.2
App.js
import React, { Component } from 'react';
import AppNavigator from './components/app.navigator';
import { StyleProvider } from 'native-base';
import getTheme from './native-base-theme/components';
import CustomTheme from './native-base-theme/variables/custom.material';
export default class App extends Component {
render() {
return (
<StyleProvider style={getTheme(CustomTheme)}>
<AppNavigator/>
</StyleProvider>
);
}
}
app.navigator.js
import React from 'react';
import { StackNavigator, TabNavigator, TabBarBottom } from 'react-navigation'; // Version can be specified in package.json
import HomeScreen from './components/HomeScreen';
import SettingsScreen from './components/SettingsScreen';
import DetailsScreen from './components/DetailsScreen';
const HomeStack = StackNavigator({
Home: { screen: HomeScreen },
Details: { screen: DetailsScreen },
});
const SettingsStack = StackNavigator({
Settings: { screen: SettingsScreen },
Details: { screen: DetailsScreen },
});
export default TabNavigator(
{
Home: { screen: HomeStack },
Settings: { screen: SettingsStack },
},
{
navigationOptions: ({ navigation }) => ({
tabBarIcon: ({ focused, tintColor }) => {
const { routeName } = navigation.state;
let iconName;
if (routeName === 'Home') {
iconName = `ios-information-circle${focused ? '' : '-outline'}`;
} else if (routeName === 'Settings') {
iconName = `ios-options${focused ? '' : '-outline'}`;
}
// You can return any component that you like here! We usually use an
// icon component from react-native-vector-icons
return <Icon name={iconName} size={25} color={tintColor} />;
},
}),
tabBarComponent: TabBarBottom,
tabBarPosition: 'bottom',
tabBarOptions: {
activeTintColor: 'tomato',
inactiveTintColor: 'gray',
},
animationEnabled: false,
swipeEnabled: false,
}
);
The screen pages are all similar except the names
settingsScreen.js , detailScreen.js, homeScreen.js
import React, { Component } from 'react';
import { View, Text, Button } from 'react-native';
export default class SettingsScreen extends Component {
render() {
return (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<Text>Settings!</Text>
<Button
title="Go to Home"
onPress={() => this.props.navigation.navigate('Home')}
/>
<Button
title="Go to Details"
onPress={() => this.props.navigation.navigate('Details')}
/>
</View>
);
}
}
I am an Android Application Developer. I have started working on React-Native. I am unable to find a way to show expandable list inside navigation drawer. Suggest a library if this functionality can be done in that. navigationOptions does not have a way to provide a list (refer code below).
I want to show expandable view like item 4
My Code is :-
import {DrawerNavigator} from 'react-navigation';
import React, {Component} from 'react';
import {
Platform,
StyleSheet,
Text,
Image,
View,
TouchableHighlight
} from 'react-native';
import Screen1 from './screen/Screen1'
import Screen2 from './screen/Screen2'
const util = require('util');
class MyHomeScreen extends React.Component {
constructor(props) {
super(props);
this.state = {
headertitle: 'ffffff'
};
}
componentWillReceiveProps(nextProps) {
navigationOptions = {
title: this.nextProps.headertitle
};
}
static navigationOptions = {
drawerLabel: 'Home',
drawerIcon: ({tintColor}) => (
<Image
source={require('./images/document.png')}
style={[
styles.icon, {
tintColor: tintColor
}
]}/>),
title: 'NIIT'
};
render() {
return (<Screen1/>);
}
}
class MyNotificationsScreen extends React.Component {
static navigationOptions = {
drawerLabel: 'Notifications',
drawerIcon: ({tintColor}) => (<Image source={require('./images/smartphone.png')} style={[styles.icon]}/>),
title: 'Gnome'
};
render() {
return (<Screen2/>);
}
}
const styles = StyleSheet.create({
icon: {
width: 24,
height: 24
}
});
const DrawerScreen = DrawerNavigator({
Screen1: {
screen: MyHomeScreen
},
Screen2: {
screen: MyNotificationsScreen
}
}, {headerMode: 'none'})
export default DrawerScreen;
I think this is a single class, simple implementation of what the OP is asking for. It uses react-navigation v5. It's a standalone component that is configured via the ExpandableDrawerProps (title is the name of parent drawer, i.e. what contains the subdrawers and has no navigation, and choices is a map of label name to navigation screen component names.) It is written in TypeScript (both of these are .tsx files), so if you're not using TypeScript, just strip out the typing.
import {
DrawerContentComponentProps,
DrawerContentScrollView,
DrawerItem,
} from '#react-navigation/drawer';
import React from 'react';
import { Text, View } from 'react-native';
import { TouchableOpacity } from 'react-native-gesture-handler';
import styles from './styles';
export type ExpandableDrawerProps = DrawerContentComponentProps & {
title: string;
choices: Map<string, string>;
};
export default class ExpandableDrawer extends React.Component<
ExpandableDrawerProps,
{
isExpanded: boolean;
}
> {
constructor(props: ExpandableDrawerProps, state: { isExpanded: boolean }) {
super(props);
this.state = state;
}
onPress = (): void => {
this.setState(() => {
return {
isExpanded: !this.state.isExpanded,
};
});
};
render = (): JSX.Element => {
return (
<View style={styles.container}>
<TouchableOpacity
activeOpacity={0.8}
onPress={this.onPress}
style={styles.heading}
>
<Text style={styles.expander}>{this.props.title}</Text>
</TouchableOpacity>
{this.state.isExpanded ? (
<DrawerContentScrollView>
<View style={styles.expandedItem}>
{[...this.props.choices.keys()].map(
(label: string): JSX.Element | null => {
const screen = this.props.choices.get(label);
if (screen != undefined) {
return (
<DrawerItem
key={label}
label={label}
onPress={(): void => {
this.props.navigation.navigate(screen);
}}
/>
);
} else {
return null;
}
}
)}
</View>
</DrawerContentScrollView>
) : null}
</View>
);
};
}
You can drop that code in a file, make a simple styles file or remove them from that code, and then you're able to use <ExpandableDrawerMenu {...expandable} />
in your normal drawer navigation.
Here's how I used it in a normal navigation drawer.
const DrawerContent = (props: DrawerContentComponentProps): JSX.Element => {
const c = new Map<string, string>();
c.set('SubItem 1', 'SubItem1');
c.set('SubItem 2', 'SubItem2');
const expandable: ExpandableDrawerProps = {
title: 'Expandable Drawer',
choices: c,
navigation: props.navigation,
state: props.state,
descriptors: props.descriptors,
progress: props.progress,
};
return (
<DrawerContentScrollView {...props}>
<View style={styles.drawerContent}>
<Drawer.Section style={styles.drawerSection}>
<DrawerItem
label="Item 1"
onPress={(): void => {
props.navigation.navigate('Item1');
}}
/>
<ExpandableDrawerMenu {...expandable} />
<DrawerItem>
label="Item 2"
onPress={(): void => {
props.navigation.navigate('Item2');
}}
/>
<DrawerItem
label="Item 3"
onPress={(): void => {
props.navigation.navigate('Item3');
}}
/>
</Drawer.Section>
</View>
</DrawerContentScrollView>
);
};
export default class Navigator extends Component {
render = (): JSX.Element => {
const Drawer = createDrawerNavigator();
return (
<NavigationContainer>
<Drawer.Navigator
drawerContent={(props: DrawerContentComponentProps): JSX.Element =>
DrawerContent(props)
}
initialRouteName="Item1"
>
<Drawer.Screen name="Item1" component={Item1Screen} />
<Drawer.Screen name="SubItem1" component={SubItem1Screen} />
<Drawer.Screen name="SubItem2" component={SubItem2Screen} />
<Drawer.Screen name="Item2" component={Item2Screen} />
<Drawer.Screen name="Item3" component={Item3Screen} />
</Drawer.Navigator>
</NavigationContainer>
);
};
}
react-navigation does not, at this time, support a collapsible menu in the drawer navigator.
You can, however, implement your own, by supplying your own contentComponent to the navigator:
const DrawerScreen = DrawerNavigator({
Screen1: {
screen: MyHomeScreen
},
Screen2: {
screen: MyNotificationsScreen
}
}, {
headerMode: 'none',
contentComponent: MyDrawer
})
const MyDrawer = (props) => ...
See the documentation for more information.
You can use something like react-native-collapsible to achieve the effect of the collapsible menu itself.
I have developed a solution for this problem. My code uses "#react-navigation/drawer": "^5.1.1" and "#react-navigation/native": "^5.0.9".
Gihub link - https://github.com/gyanani-harish/ReactNative-ExpandableDrawerMenu
I use react-navigation and take some references to create a drawer , it looks fine .
But i want to add a headerView and can't find the way to do it .
Is any possible to create a drawer headerView just like Android?
Ant help would be appreciated.
Here is MyDrawer.js:
import React, { Component } from 'react';
import { Image, ScrollView } from 'react-native';
import { DrawerNavigator, DrawerItems } from 'react-navigation';
import PageOne from './PageOne';
import PageTwo from './PageTwo';
class MyDrawer extends Component {
render() {
const TheDrawer = DrawerNavigator({
PageOne: {
screen: PageOne,
navigationOptions: {
drawerLabel: 'It\s page One',
drawerIcon: () => (
<Image source={require('../img/nav_icon_home.png')} />
),
},
},
PageTwo: {
screen: PageTwo,
navigationOptions: {
drawerLabel: 'It\'s page Two',
drawerIcon: () => (
<Image source={require('../img/nav_icon_home.png')} />
),
},
},
}, {
drawerWidth: 300,
contentComponent: props => <ScrollView>
<DrawerItems {...props}
activeTintColor='#008080'
activeBackgroundColor='#EEE8AA'
inactiveTintColor='#20B2AA'
inactiveBackgroundColor='#F5F5DC'
style={{backgroundColor: '#F5F5DC'}}
labelStyle={{color: '#20B2AA'}}
/>
</ScrollView>
});
return (
<TheDrawer />
);
}
};
export default MyDrawer;