React - how to add header when I have bottom tab navigation - reactjs

I'm trying to achieve a Instagram-like navigation
I have a buttom tab navigation in App.js
import React from 'react';
import { StyleSheet, Text, View, Image } from 'react-native';
import { createAppContainer, createBottomTabNavigator} from 'react-navigation';
import Ionicons from 'react-native-vector-icons/Ionicons';
import Home from './views/Home'
import Search from './views/Search'
const MainNavigator = createBottomTabNavigator({
Home: { screen: Home },
Search: { screen: Search },
}, {
defaultNavigationOptions: ({ navigation }) => ({
tabBarIcon: ({ focused, horizontal, tintColor }) => {
const { routeName } = navigation.state;
let IconComponent = Ionicons;
let iconName;
if(routeName === 'Home'){
iconName = `ios-home`;
}
if(routeName === 'Search'){
iconName = `ios-search`;
}
return <IconComponent name={iconName} size={25} color={tintColor} />;
}
}),
initialRouteName: 'Search',
tabBarOptions: {
activeTintColor: '#fff',
activeBackgroundColor: '#4c399c',
inactiveTintColor: '#f1f3f5',
inactiveBackgroundColor: '#5442a0',
showLabel: false
},
});
const App = createAppContainer(MainNavigator);
export default App;
I'll have more than two views at the bottom.
The top bar will have a centered logo on all views, and some views will have 1 left button and/or 1 right button.
What I'm trying to achieve is to not render the header bar in every view, but to declare one globally (like the bottom navigation) and add the custom buttons on the few views that will have them

put the tab navigation as the parent, and add a stack navigation inside each tab.

An easy way to do this is using the Header component from react-native-elements. You just need to add this to the screen that you want the header on.
It's really easy to add the buttons to open drawer or anything else that you need.
For this to work, don't forget to add the header: null to the stack navigators, otherwise you'll end up with 2 headers on your screen.
Example below:
<React.Fragment>
<Header
statusBarProps={{ barStyle: 'light-content' }}
barStyle="light-content"
leftComponent={
<SimpleIcon
name="menu"
color="#34495e"
size={20}
/>
}
centerComponent={{ text: 'HOME', style: { color: '#34495e' } }}
containerStyle={{
backgroundColor: 'white',
justifyContent: 'space-around',
}}
/>
</React.Fragment>

This code will display centered the header on each screen of your BottomTabNavigator - MainNavigator
const AppNavigator = createStackNavigator({
Home: {screen: MainNavigator}
},
defaultNavigationOptions: {title: 'Instagram'},
headerLayoutPreset: 'center'
})
const App = createAppContainer(AppNavigator);
export default App;

Related

React native createDrawerNavigator is not working

Could you please help me on this small issue.
I am very very new to React native and here i am training in learn react navigation. My problem is Drawer navigator is not working when i try to swap from left to right. But bottom navigator is working. Any idea whats wrong with this please.
Also: if you can please send me a good sample to learn this area.
I have some samples, but most of the samples are outdated.
MyCode:
import React from 'react';
import {TouchableOpacity, View, Text, Image} from 'react-native';
import {createAppContainer, createSwitchNavigator} from 'react-navigation';
import {createStackNavigator} from 'react-navigation-stack';
import {createBottomTabNavigator} from 'react-navigation-tabs';
import {createDrawerNavigator} from 'react-navigation-drawer';
import HomeScreen2 from '../screens/HomeScreen2';
import HomeScreen from '../screens/HomeScreen';
import Setup from '../screens/Setup';
const HomeStack = createStackNavigator(
{
//Defination of Navigaton from home screen
Home: { screen: HomeScreen },
// Details: { screen: ProfileScreen },
},
{
defaultNavigationOptions: {
//Header customization of the perticular Screen
headerStyle: {
backgroundColor: '#42f44b',
},
headerTintColor: '#FFFFFF',
title: 'Home',
//Header title
},
}
);
const SettingsStack = createStackNavigator(
{
//Defination of Navigaton from setting screen
Settings: { screen: Setup },
},
{
defaultNavigationOptions: {
//Header customization of the perticular Screen
headerStyle: {
backgroundColor: '#42f44b',
},
headerTintColor: '#FFFFFF',
title: 'Settings',
//Header title
},
}
);
const TabMain = createBottomTabNavigator(
{
TAB1: HomeStack,
TAB2: SettingsStack,
},
{
initialRouteName: 'TAB1',
}
)
const DrawHomeView = createStackNavigator({
HomeV: {screen: HomeScreen2}},
{
headerMode: 'float',
navigationOptions: ({navigation}) => ({
headerStyle: {
backgroundColor: 'rgb(255,45,85)',
paddingLeft: 10,
paddingRight: 10
},
title: 'Map View',
headerTintColor: 'white',
headerLeft: <View>
<TouchableOpacity
onPress={() => {
if (navigation.state.isDrawerOpen === false) {
navigation.dispatch(DrawerActions.openDrawer());
} else {
navigation.dispatch(DrawerActions.closeDrawer());
}
}}>
<Text>Menu</Text>
</TouchableOpacity>
</View>
})
});
const DrawSettingsView = createStackNavigator({
SettingsV: {screen: Setup}},
{
headerMode: 'float',
navigationOptions: ({navigation}) => ({
headerStyle: {
backgroundColor: 'rgb(255,45,85)',
paddingLeft: 10,
paddingRight: 10
},
title: 'Map View',
headerTintColor: 'white',
headerLeft: <View>
<TouchableOpacity
onPress={() => {
if (navigation.state.isDrawerOpen === false) {
navigation.dispatch(DrawerActions.openDrawer());
} else {
navigation.dispatch(DrawerActions.closeDrawer());
}
}}>
<Text>Menu</Text>
</TouchableOpacity>
</View>
})
});
const TabMain2 = createDrawerNavigator(
{
TAB3: DrawHomeView,
TAB4: DrawSettingsView,
},
{
initialRouteName: 'TAB3',
}
)
export default createAppContainer(createSwitchNavigator(
{
Sub1: TabMain,
Sub2: TabMain2,
},
{
initialRouteName: 'Sub2',
}
));
Okay. After some dabbling with your code and the docs : https://reactnavigation.org/docs/nesting-navigators/
and please read the docs and try their examples as they are excellent descriptive and available for real time execution on snack.
For the second part of the question, i put together an example for you:
import * as React from 'react';
import { Button, View, Text } from 'react-native';
import { createDrawerNavigator } from '#react-navigation/drawer';
import { NavigationContainer } from '#react-navigation/native';
import { createBottomTabNavigator } from '#react-navigation/bottom-tabs';
import MaterialCommunityIcons from 'react-native-vector-icons/MaterialCommunityIcons';
//Import necessary components
//Create Screens, Dummy screens in this case.
function NotificationsScreen({ navigation }) {
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Button onPress={() => navigation.goBack()} title="Go back home" />
</View>
);
}
function Feed ({ navigation, route }) {
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Text style={{fontSize: 40}}>Feed </Text>
</View>
);}
function Home ({ navigation, route }) {
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Text style={{fontSize: 40}}> Home </Text>
</View>
);}
// Here is your questions answer, just create a Bottom Navigator
// and a Drawer Navigator and nest them in each other after declaring your
// screens.
const Tab = createBottomTabNavigator();
const Drawer = createDrawerNavigator();
function HomeScreen({ navigation }) {
return (
<Tab.Navigator>
//Put your Tab screens here.
<Tab.Screen name="Home" component={Home} />
<Tab.Screen name="Feed" component={Feed} />
</Tab.Navigator>
);
}
export default function App() {
return (
// For the main export create a navigation container and declare the
// Drawer Navigator inside the main navigation container, then use that to
// To Access your Tab navigator "HomeScreen" and put whatever else you
// Want in your Drawer Navigator.
<NavigationContainer>
<Drawer.Navigator initialRouteName="Home">
<Drawer.Screen name="Home" component={HomeScreen} />
<Drawer.Screen name="Notifications" component={NotificationsScreen} />
</Drawer.Navigator>
</NavigationContainer>
);
}
Explanation: You are only allowed to nest navigators within each other and not within the main navigation container.
This code has been tested using expo-cli 3.18.4

How to navigate between screens without adding it to tabNavigation in react native

Suppose you have a react native app that has a flow that navigates between screens upon data entry, how would you navigate through these screens without having to add these screens to a stackNavigation or createbottomtabnavigator?
For example here is my app upon being on home page.
1)
2)
3) It gets added to navigation tab menu :(
here is the navigation code.
import React from "react";
// import HomeView from "./components/screens/Home";
import AddPostView from "./containers/addPost";
import SettingsView from "./containers/settings";
import ContentView from "./components/screens/AddContent";
import Icon from "react-native-vector-icons/AntDesign";
import { createAppContainer } from "react-navigation";
import DashboardView from "./components/screens/Dashboard";
import { createMaterialBottomTabNavigator } from "react-navigation-material-bottom-tabs";
const AppNavigator = createMaterialBottomTabNavigator(
{
Home: {
screen: AddPostView, // shows the title screen is there a way i can nest the screens apart of this screen ?
navigationOptions: {
tabBarIcon: ({ tintColor }) => (
<Icon name="home" color={tintColor} size={24} />
)
}
},
Content: {
screen: ContentView, // shows add content screen.
labeled: false,
navigationOptions: {
tabBarIcon: false,
tabBarLabel: false
}
},
Dashboard: {
screen: DashboardView,
navigationOptions: {
tabBarIcon: ({ tintColor }) => (
<Icon name="dashboard" color={tintColor} size={24} />
)
}
},
Settings: {
screen: SettingsView,
navigationOptions: {
tabBarIcon: ({ tintColor }) => (
<Icon name="user" color={tintColor} size={24} />
)
}
}
},
{
initialRouteName: "Home",
activeColor: "#f0edf6",
tabBarLabel: "Content",
inactiveColor: "#333333",
barStyle: {
backgroundColor: "#B9D2B1",
justifyContent: "center",
alignItems: "center"
}
}
);
export default createAppContainer(AppNavigator);
AddPost.jsx
import React, { Component, Fragment } from "react";
import { View, Text, Button, StyleSheet } from "react-native";
import { Subheading, Dialog } from "react-native-paper";
import PostForm from "../forms/createPost/createPost";
export default class AddPostView extends Component {
state = {
title: "",
content: "",
touched: {
title: false,
content: false
}
};
titleChange = title => {
this.setState({ title });
};
validate = field => {
console.log("tet", field);
this.setState({
touched: { ...this.state.touched, [field]: true }
});
console.log(this.state.touched);
};
contentChange = content => {
this.setState({ content });
};
render() {
const isEnabled = this.state.title.length > 6 ? false : true;
return (
<Fragment>
<Subheading style={styles.labels}> Add An Entry</Subheading>
<PostForm
title={this.state.title}
titleChange={this.titleChange}
disButton={isEnabled}
hasError={this.state.touched}
onSubmit={() => this.props.navigation.navigate("Content")}
validateTitle={() => this.validate("title")}
/>
</Fragment>
);
}
}
const styles = StyleSheet.create({
labels: {
textAlign: "center",
fontWeight: "bold",
fontSize: 25,
padding: 20,
marginTop: 50
}
});
I found a way to do this. Here were my steps
1) Create a new file called otherNav.jsx (this can handle multiple screens for different scenarios, for now i just need it to navigation to a form)
import React from "react";
import { createStackNavigator } from "react-navigation-stack";
import { createAppContainer } from "react-navigation";
import ContentView from "./containers/addContent";
import Icon from "react-native-vector-icons/AntDesign";
const OtherNavigation = createStackNavigator(
{
Content: {
screen: ContentView
}
},
{
headerMode: "none",
activeColor: "#f0edf6",
tabBarLabel: "Content",
inactiveColor: "#333333",
barStyle: {
backgroundColor: "#B9D2B1",
justifyContent: "center",
alignItems: "center"
}
}
);
export default createAppContainer(OtherNavigation);
2) Call this in AuthNav where all the navigations live
import React, { Component } from "react";
import { createAppContainer } from "react-navigation";
import AuthLoadingScreen from "./AuthLoadingScreen";
import AuthNavigation from "./splashNav";
import AppNavigator from "./loggedInNav";
import OtherNavigation from "./otherNav";
import { createStackNavigator } from "react-navigation-stack";
export default createAppContainer(
createStackNavigator(
{
AuthLoading: {
screen: AuthLoadingScreen // intimidiary between App && Auth checks for token and such
},
App: AppNavigator,
Content: OtherNavigation,
Auth: AuthNavigation
},
{
initialRouteName: "AuthLoading",
headerMode: "none"
}
)
);
3) Now this will flow accordingly
render() {
const isEnabled = this.state.title.length > 6 ? false : true;
return (
<Fragment>
<Subheading style={styles.labels}> Add An Entry</Subheading>
<PostForm
title={this.state.title}
titleChange={this.titleChange}
disButton={isEnabled}
hasError={this.state.touched}
onSubmit={() => this.props.navigation.navigate("Content")}
validateTitle={() => this.validate("title")}
/>
</Fragment>
);
}
}
So now we have this (end result its not added to bottomNav)
1)
2)

I want to give box shadow to the Header according to below in image in React native navigation

I want to give box shadow to Header according to below in image in React native navigation and after giving borderBottomRadius there is a little white color showing from both right and left side i want to remove that color and want to make that according to the home.js background color.
here is code of header:
const stackNav = createStackNavigator({
Home : {
screen: Routes.Home,
navigationOptions: ({navigation}) => ({
title: "Home",
headerTitleStyle: {
fontWeight: '600',
color: '#e91e63',
},
headerStyle:{
borderBottomLeftRadius:10,
borderBottomRightRadius:10,
},
headerLeft:(<TouchableOpacity onPress={() => navigation.openDrawer()}>
<View style={{
paddingLeft: 15
}}>
<IOSIcon
name="ios-menu"
size={40}
color='#e91e63'
/>
</View>
</TouchableOpacity>
),
})
}
});
here is Home.js
import React from 'react';
import { View,Text, StyleSheet,Dimensions } from 'react-native';
class Home extends React.Component {
render() {
return(
<View style={styles.container}>
<Text>Home.js</Text>
</View>
)
}
}
export default Home;
const styles = StyleSheet.create({
container:{
backgroundColor:'#F0F3F5',
flex:1,
}
})
what i want in header the box shadow
want to get rid of that mark area or change color according to Home.js color
Since you didn't provide any code, the best we can do is guess.
Maybe you're adding the box-shadow to the parent container (wrapper) instead of the white rounded 'plate'?

React native + expo topbar Material navigation leaves gap at top

I'm trying to add a tabbed navigation to a React Native app, also using expo if that matters, and whenever I do this I get a big chunk of white at the top of the screen. I'm not seeing what's causing this though, the status bar background shouldn't be pushing it down and as far as I can tell changing the height style of my navigation or main view doesn't do anything.
This looks like:
The complete source to recreate this is:
// utils/colors.js
export const white = '#fff'
export const orange = '#f26f28'
// App.js
import React, { Component } from 'react'
import { StyleSheet, View, StatusBar, Dimensions } from 'react-native'
import {
createMaterialTopTabNavigator,
createStackNavigator
} from 'react-navigation'
import { Constants } from 'expo'
import List from './components/List'
import Add from './components/Add'
import { orange, white } from './utils/colors'
function StatusBarBackground ({ backgroundColor, ...props }) {
return (
<View style={{ backgroundColor, height: Constants.statusBarHeight }}>
<StatusBar translucent backgroundColor={backgroundColor} {...props} />
</View>
)
}
const Tabs = createMaterialTopTabNavigator({
List: {
screen: List,
navigationOptions: {
tabBarLabel: 'List',
},
},
Add: {
screen: Add,
navigationOptions: {
tabBarLabel: 'Add',
},
},
}, {
navigationOptions: {
header: null
},
tabBarOptions: {
activeTintColor: white,
style: {
height: 56,
backgroundColor: orange,
shadowColor: 'rgba(0, 0, 0, 0.24)',
shadowOffset: {
width: 0,
height: 3
},
shadowRadius: 6,
shadowOpacity: 1
}
}
})
const MainNavigator = createStackNavigator({
Home: {
screen: Tabs,
},
})
export default class App extends Component {
render() {
return (
<View style={{flex: 1}}>
<StatusBarBackground backgroundColor={orange} barStyle="light-content" />
<MainNavigator />
</View>
)
}
}
The Add and List components are just a view with a text, both look similar to this:
import React, { Component } from 'react'
import { View, Text } from 'react-native'
class Add extends Component {
render() {
return (
<View>
<Text style={{fontSize: 20}}>Add</Text>
</View>
)
}
}
export default Add
You are adding Your Tab Navigator inside Stack Navigator, That is why that white header is showing from Stack Navigator.
1) If You want to add header then style your header like below
const MainNavigator = createStackNavigator({
Home: {
screen: Tabs,
},
},{
navigationOptions:{
headerStyle : {
backgroundColor:'#243346'
},
headerTintColor:"#fff"
},
})
2) If you want to remove header then you can either remove your Tab Navigator from Stack Navigator or add headerMode:'none' inside navigationOprions object.

How to change background color of drawer in react-navigation fully

How can I change Background Color of the drawer fully? I don't need to change drawer items need to change the background color of the drawer fully. By default, it's white while I need to make it Green. Is there any demo example?
Old question, but this may help people that are looking for this solution. On createDrawerNavigator you have a drawerConfig property called drawerBackgroundColor.
Example:
import React from 'react';
import { createDrawerNavigator } from 'react-navigation';
import Home from '../screens/Home';
import Screen2 from '../screens/Screen2';
export default createDrawerNavigator({
Home,
Screen2
}, {
drawerPosition: 'left',
drawerBackgroundColor: '#0000FF',
});
You can read more about it, on React Navigation documentation: https://reactnavigation.org/docs/en/drawer-navigator.html
This Current example can help you , This the DrawerNavigtor using DrawerContent , Need to change the style of DrawerContent
const Main = DrawerNavigator({
home: { screen: HomePage },
}, {
drawerWidth: 250,
drawerPosition: 'right',
contentComponent: props => <DrawerContent {...props} />,
});
export default Main;
You can Change the style by using the this code below
class DrawerContent extends Component {
render() {
return (
<ScrollView style={styles.container}>
<View style={{ flex: 1 }}>
<Button transparent info onPress={() => { this.handlechange(); }}>
<Text style={{ fontSize: 16 }}>Change Email</Text>
</Button>
</View>
</ScrollView>
);
}
}
const styles = {
container: {
flex: 1,
padding: 20,
backgroundColor: 'Green',
},
};
export default DrawerContent;
This can change the background color

Resources