React native BottomTabNavigator with DrawerNavigator, how to keep bottom navigator visible all the time

7.8k views Asked by At

I have gone through various posts on SO and github about react navigation, but most of them are a combination of react native stack navigator with drawer navigator. I couldn't find anything that could help fix my problem.

What i am trying to do is i have a bottom tab bar with five screens which load nicely with correct data, i want to add a drawer navigator to provide more screens and have different data. I have managed to build the drawer navigator on top of the tab navigator but when the drawer is opened, it overlaps the bottom tab bar and hence bottom tab navigation is useless as long as the drawer is open. Also adding the tabs under the drawer navigator shows Tabs as one of the options in the drawer menu.

What i want to achieve is, 1. Have a bottom tab navigation visible all the time. 2. When the drawer is open the drawer menu opens and does not over lap the bottom tab bar. 3. And the drawer menu should have only those screens which can be navigated from the drawer menu.

Below is my navigation code,

    import React from 'react'

    // Navigators
    import { DrawerNavigator, StackNavigator, createBottomTabNavigator } from 'react-navigation'

    // TabNavigator screens
    import ProfileConnector from '../connectors/ProfileConnector'
    import InboxConnector from '../connectors/InboxConnector'
    import AttendanceConnector from '../connectors/AttendanceConnector'
    import Results from '../layouts/results/Results'
    import TimetableConnector from '../connectors/TimetableConnector'
    import Icon from 'react-native-vector-icons/Entypo'
    import {Dimensions} from 'react-native'

    const deviceW = Dimensions.get('window').width

    const basePx = 375

    function px2dp(px) {
    return px *  deviceW / basePx
    }

    import Gallery from '../layouts/gallery/Gallery'

    export const Tabs = createBottomTabNavigator({
        Profile: { 
            screen: ProfileConnector,
            navigationOptions: {
                tabBarLabel: 'Profile',
                tabBarIcon: ({tintColor}) => <Icon name="user" size={px2dp(22)} color={tintColor}/>,
            },
        },
        Inbox: { 
            screen: InboxConnector,
            navigationOptions: {
                tabBarLabel: 'Inbox',
                tabBarIcon: ({tintColor}) => <Icon name="inbox" size={px2dp(22)} color={tintColor}/>,
            },
        },
        Attendance: {
            screen: AttendanceConnector,
            navigationOptions: {
                tabBarLabel: 'Attendance',
                tabBarIcon: ({tintColor}) => <Icon name="hand" size={px2dp(22)} color={tintColor}/>,
            },
        },
        Timetable: {
            screen: TimetableConnector,
            navigationOptions: {
                tabBarLabel: 'Timetable',
                tabBarIcon: ({tintColor}) => <Icon name="calendar" size={px2dp(22)} color={tintColor}/>,
            },
        },
        Results: {
            screen: Results,
            navigationOptions: {
                tabBarLabel: 'Results',
                tabBarIcon: ({tintColor}) => <Icon name="bar-graph" size={px2dp(22)} color={tintColor}/>,
            },
        },
    }, {
        initialRouteName: 'Inbox',
        tabBarPosition: 'bottom',
        swipeEnabled: true,
        tabBarOptions: {
            activeTintColor: 'teal',
            inactiveTintColor: '#424949',
            activeBackgroundColor: "white",
            inactiveTintColor: '#424949',
            labelStyle: { fontSize: 14 },
            style : { height : 50}
        }
    });

    export const Drawer = DrawerNavigator({
        Tabs: {screen: Tabs},
        Gallery: { screen: Gallery },
    },{
        drawerWidth: 250,
        drawerPosition: 'left',
        drawerOpenRoute: 'DrawerOpen',
        drawerCloseRoute: 'DrawerClose',
        drawerToggleRoute: 'DrawerToggle',
    })

Can anybody help me with this please?

Thanks, Vikram

2

There are 2 answers

3
ehsan On

Well, i tried and it's close to what you want. Background of DrawerNavigator is transparent and in CustomDrawerContentComponent, height is assigned to a view to make bottom tab bar visible. Hope that works for you.

const CustomDrawerContentComponent = (props) => (
    <View style={{height:500}} >
    <ScrollView
              horizontal
              style={{ backgroundColor: 'blue'}}
            ><DrawerItems {...props} />
      </ScrollView>
    </View>
);

const Drawer = createDrawerNavigator({
           Tabs: {screen: Tabs},
           Gallery: { screen: Home },
       },{
          drawerBackgroundColor : 'transparent',
          contentComponent: props => <CustomDrawerContentComponent {...props} />
        }
    )
1
vishnu prasath On
/**
 * Sample React Native App
 * https://github.com/facebook/react-native
 *
 * @format
 * @flow`enter code here`
 */
import React, {Component} from 'react';
import {Platform, StyleSheet, Text, View,Button} from 'react-native';
import Icon from 'react-native-vector-icons/Ionicons';
import {
  createBottomTabNavigator,
  createStackNavigator,
  createAppContainer,
  createDrawerNavigator,
  createSwitchNavigator,
} from 'react-navigation';
import Icons from 'react-native-ionicons';
const instructions = Platform.select({
  ios: 'Press Cmd+R to reload,\n' + 'Cmd+D or shake for dev menu',
  android:
    'Double tap R on your keyboard to reload,\n' +
    'Shake or press menu button for dev menu',
});

class DetailsScreen extends React.Component {
  render() {
    return (
      <View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
        <Text>Details!</Text>
      </View>
    );
  }
}

class HomeScreen extends React.Component {
  render() {
    return (
      <View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
        {/* other code from before here */}
        <Button
          title="Go to Details"
          onPress={() => this.props.navigation.navigate('Details')}
        />
      </View>
    );
  }
}

class SettingsScreen extends React.Component {
  render() {
    return (
      <View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
        {/* other code from before here */}
        <Button
          title="Go to Details"
          onPress={() => this.props.navigation.navigate('Details')}
        />
      </View>
    );
  }
}
class LoginScreen extends React.Component {
  render() {
    return (
      <View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
        {/* other code from before here */}
        <Button
          title="Login"
          onPress={() => this.props.navigation.navigate('Home')}
        />
      </View>
    );
  }
}

const HomeStack = createStackNavigator({
  Home: {screen:HomeScreen,
    navigationOptions: ({ navigation }) => ({
      title: `Home`,
      headerLeft:  <Icon name='md-menu' size={30} onPress={()=>{navigation.openDrawer()}}/>,
      headerStyle:{
        textAlign:'center',
        alignContent: 'center',
      }
    }),
  },
  Details:{screen: DetailsScreen,
    navigationOptions: ({ navigation }) => ({
      title: `Details`,
      //headerLeft:  <Icon name='md-menu' size={30}/>,
      headerStyle:{
        alignContent: 'center',
      }
    }),
  },
},{
   initialRouteName: 'Home',

}

);

const SettingsStack = createStackNavigator({
  Settings:{screen: SettingsScreen,
    navigationOptions: ({ navigation }) => ({
      title: `Privacy`,
      headerLeft:  <Icon name='md-menu' size={30}/>,
      headerStyle:{
        alignContent: 'center',
      }
    }),
  },
  Details: {screen:DetailsScreen,
    navigationOptions: ({ navigation }) => ({
      title: `Privacy Details`,
      //headerLeft:  <Icon name='md-menu' size={30}/>,
      headerStyle:{
        alignContent: 'center',
      }
    }),
  },
});
const bottomTabNavigator = createBottomTabNavigator(
  {
    Home: HomeStack,
    Settings: SettingsStack,
  }

)
// const bottomStack = createStackNavigator({
//   bottomTabNavigator
// },{

//     defaultNavigationOptions:({navigation})=>{
//       return {
//         headerLeft:  <Icon name='md-menu' size={30} onPress={()=>{navigation.openDrawer()}}/>,
//         title:navigation.state.routeName[navigation.state.index]


//       }
//     }

// })
const dashboardStack = createDrawerNavigator({
  Dashboard: bottomTabNavigator,

},)
const authStack = createSwitchNavigator({
  Login:LoginScreen,
  Dashboard:dashboardStack

})

export default createAppContainer(authStack);






const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
    backgroundColor: '#F5FCFF',
  },
  welcome: {
    fontSize: 20,
    textAlign: 'center',
    margin: 10,
  },
  instructions: {
    textAlign: 'center',
    color: '#333333',
    marginBottom: 5,
  },
});