0

How to implement a buttom navigator that containt a button that handle DrawerNav display

DrawerNav button inside ButtomNavigation

Rajendran Nadar
  • 4,962
  • 3
  • 30
  • 51
Aymen
  • 248
  • 3
  • 15

1 Answers1

0

To be able to do it, first you would have to add your custom tab bar, by overriding the tabBar property on the Tab.Navigator component. Here is an example from the official React Navigation docs.

Then you would have to add a button to your custom tab bar, which purpose would be to open the drawer screen (navigation.openDrawer).

Here's an example how you could do it:

import React from 'react';
import {
  Button,
  SafeAreaView,
  Text,
  TouchableOpacity,
  View,
} from 'react-native';
import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
import { createDrawerNavigator } from '@react-navigation/drawer';

const Tab = createBottomTabNavigator();

const TabItem = ({ label, onPress, isFocused = false }) => (
  <TouchableOpacity
    accessibilityRole="button"
    onPress={onPress}
    style={{
      flex: 1,
      padding: 20,
      alignItems: 'center',
      justifyContent: 'center',
    }}>
    <Text style={{ color: isFocused ? '#673ab7' : '#222' }}>{label}</Text>
  </TouchableOpacity>
);

const MyTabBar = ({ state, descriptors, navigation }) => {
  const focusedOptions = descriptors[state.routes[state.index].key].options;

  if (focusedOptions.tabBarVisible === false) {
    return null;
  }

  const onOpenDrawerPress = () => {
    navigation.openDrawer();
  };

  return (
    <View style={{ flexDirection: 'row' }}>
      <TabItem label="Open drawer" onPress={onOpenDrawerPress} />
      {state.routes.map((route, index) => {
        const { options } = descriptors[route.key];
        const label =
          options.tabBarLabel !== undefined
            ? options.tabBarLabel
            : options.title !== undefined
            ? options.title
            : route.name;

        const isFocused = state.index === index;

        const onPress = () => {
          const event = navigation.emit({
            type: 'tabPress',
            target: route.key,
            canPreventDefault: true,
          });

          if (!isFocused && !event.defaultPrevented) {
            navigation.navigate(route.name);
          }
        };

        return (
          <TabItem label={label} onPress={onPress} isFocused={isFocused} />
        );
      })}
    </View>
  );
};

const TabOneScreen = () => (
  <SafeAreaView>
    <Text>Tab One screen</Text>
  </SafeAreaView>
);

const TabTwoScreen = () => (
  <SafeAreaView>
    <Text>Tab Two screen</Text>
  </SafeAreaView>
);

const TabNavigator = () => {
  return (
    <Tab.Navigator tabBar={MyTabBar}>
      <Tab.Screen name="TabOneScreen" component={TabOneScreen} />
      <Tab.Screen name="TabTwoScreen" component={TabTwoScreen} />
    </Tab.Navigator>
  );
};

const Drawer = createDrawerNavigator();

const Notifications = ({ navigation }) => (
  <SafeAreaView>
    <Text>Notifications Screen</Text>
    <Button title="Open drawer" onPress={navigation.openDrawer} />
  </SafeAreaView>
);

const Router = () => {
  return (
    <Drawer.Navigator>
      <Drawer.Screen name="Home" component={TabNavigator} />
      <Drawer.Screen name="Notifications" component={Notifications} />
    </Drawer.Navigator>
  );
};

export default Router;

Maybe the only "drawback" would be that you have to customize the custom tab bar so that you can achieve your desired look and feel. However, that could also prove to be better in the long run, as you have more control over your tab bar and its items.

Kapobajza
  • 2,254
  • 15
  • 22