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;
Related
I have made my custom header and i want to remove react-native default header.
I have tried with
Setting option "header: null" in navigationOptions of
createBottomTabNavigator
header:null in HomeScreen.js file
but it's not working. Please help to solve this issue. Here is my navigation code. I am attaching screenshot exactly what i want to remove.
import React from "react";
import { Platform } from "react-native";
import { createStackNavigator } from "react-navigation-stack";
import { createBottomTabNavigator } from "react-navigation-tabs";
import TabBarIcon from "../components/TabBarIcon";
import HomeScreen from "../screens/HomeScreen";
import SavedScreen from "../screens/SavedScreen";
import BookingScreen from "../screens/BookingScreen";
import BeAHostScreen from "../screens/BeAHostScreen";
import ReferEarnScreen from "../screens/ReferEarnScreen";
import BookingInnerScreen from "../screens/BookingInnerScreen";
import { Icon } from "react-native-elements";
const config = Platform.select({
web: { headerMode: "screen" },
default: {}
});
const tabNavigator = createBottomTabNavigator({
Home: {
screen: HomeScreen,
defaultNavigationOptions: {
title: "App Name Here"
},
navigationOptions: {
tabBarLabel: "Home",
tabBarOptions: {
activeTintColor: "#00E8AC"
},
tabBarIcon: ({ focused }) => {
return focused ? (
<Icon name="md-home" type="ionicon" color="#00E8AC" />
) : (
<Icon name="md-home" type="ionicon" color="#ccc" />
);
}
}
},
Saved: {
screen: SavedScreen,
defaultNavigationOptions: {
title: "Saved"
},
navigationOptions: {
tabBarLabel: "Saved",
tabBarOptions: {
activeTintColor: "#00E8AC"
},
tabBarIcon: ({ focused }) => {
return focused ? (
<Icon name="md-heart" type="ionicon" color="#00E8AC" />
) : (
<Icon name="md-heart" type="ionicon" color="#ccc" />
);
}
}
}
});
const MyApp = createStackNavigator(
{
BookingInner: BookingInnerScreen,
Tabs: {
screen: tabNavigator
}
},
{
initialRouteName: "Tabs"
}
);
export default MyApp;
Try this :
const MyApp = createStackNavigator(
{
BookingInner: BookingInnerScreen,
Tabs: {
screen: tabNavigator
}
},
{
initialRouteName: "Tabs",
headerMode: 'none',
}
);
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 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
recently I have a problem on a simple DrawerNavigator inside StackNavigator. My goal is to get both the back function from StackNavigator and DrawerNavigator side menu when I click BurgerMenu icon on the StackNavigator's header.
Here's my current code
import React, { Component } from 'react';
import { TouchableHighlight } from 'react-native';
import SvgUri from 'react-native-svg-uri';
import { StackNavigator } from 'react-navigation';
import { DrawerNavigator } from "react-navigation";
import SideBar from './SideBar';
import Screen1 from './Screen1';
import Screen2 from './Screen2';
import Screen3 from './Screen3';
export default class App extends React.Component {
render() {
return <StackNav />;
}
}
class BurgerMenu extends React.Component {
render() {
return (
<TouchableHighlight
onPress={() => this.props.navigation.navigate("DrawerOpen")}>
<SvgUri
width="30"
height="30"
source={require("Project_01/app/images/menu.svg")}
/>
</TouchableHighlight>
);
}
}
const DrawerNav = DrawerNavigator(
{
Screen1: { screen: Screen1 }
},
{
contentComponent: props => <SideBar {...props} />
}
);
const StackNav = StackNavigator(
{
Screen1: {
screen: DrawerNav,
},
Screen2: {
screen: Screen2,
},
Screen3: {
screen: Screen3,
},
},
{
initialRouteName: 'DrawerNav',
navigationOptions: {
headerRight: <BurgerMenu /> ,
title: "Header"
},
},
);
As you can see Im adding headerRight with BurgerMenu component to navigationOptions in StackNavigator.
In BurgerMenu class I added TouchableHighlight with " onPress={() => this.props.navigation.navigate("DrawerOpen")}> " which I mean open up the DrawerNavigator.
Unfortunately when I press that, i got an error message says "undefined is not an object (evaluating 'e.props.navigation.navigate').
Can someone help me please
Try changing this:
navigationOptions: {
headerRight: <BurgerMenu /> ,
title: "Header"
},
by this:
navigationOptions: ({navigation}) => ({
headerRight: <BurgerMenu navigation={navigation} />,
title: "Header"
}),
Also you can refer to this example on my github.
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