Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Adding a custom 'Add' button to createMaterialBottomTabNavigator in react navigation 5

I'm making a project (react native, expo, react navigation 5) where I wanted to add a custom 'add' button to the bottom tabs, but since...

A navigator can only contain 'Screen' components as its direct children

...I needed to find a way to pass my custom component.

Seemed easy enough, I mean there are docs:

  • https://reactnavigation.org/docs/material-bottom-tab-navigator
  • https://reactnavigation.org/docs/bottom-tab-navigator
  • https://reactnavigation.org/docs/custom-navigators/

...but in looking at these and the questions from others I either only found muy complicado examples or examples of how to achieve this in earlier versions.

In the end I found a simple solution that so far works like a charm (fully grateful to any suggestions as to why this might be a terrible idea).

Figured I post my solution if anyone is in a similar pickle. See answer below.

like image 687
Osa Gambas Avatar asked Mar 03 '23 18:03

Osa Gambas


1 Answers

Place the component outside the navigator, and position it above the tabs with css. Adjust the icons of the tabs to the left and right as seen in the example.

Like I said above, suggestions on how to achieve this in a different way warmly welcome, but haven't encountered any issues yet (knock on wood).

Here's what it looks like:

enter image description here

And here's the bunny:

import React from 'react';
import { createMaterialBottomTabNavigator } from '@react-navigation/material-bottom-tabs';
import { Ionicons, MaterialIcons, FontAwesome } from '@expo/vector-icons';

import AddButton from '../../components/UI/AddButton';
import SpotlightProductsScreen from './SpotlightProductsScreen';
import ProductsScreen from './ProductsScreen';
import UserSpotlightScreen from './../user/UserSpotlightScreen';
import UserProductsScreen from './../user/UserProductsScreen';


const ProductsOverviewScreen = props => {

  const Tab = createMaterialBottomTabNavigator();

  return (
    <>
      <AddButton
        navigation={props.navigation}
        style={{
          position: 'absolute',
          zIndex: 99,
          bottom: 5,
          alignSelf: 'center',
          shadowColor: 'black',
          shadowOpacity: 0.15,
          shadowOffset: { width: 0, height: 2 },
          shadowRadius: 8,
          elevation: 3 //Because shadow only work on iOS, elevation is same thing but for android.
        }}
      />
      <Tab.Navigator
        initialRouteName="Spotlight"
        labeled={false}
        shifting={true}
        activeColor="#f0edf6"
        inactiveColor="#3e2465"
        barStyle={{ backgroundColor: 'rgba(127,63,191,.9)' }}
      >
        <Tab.Screen
          name="Spotlight"
          component={SpotlightProductsScreen}
          options={{
            tabBarIcon: ({ color }) => (
              <Ionicons
                name={
                  Platform.OS === 'android'
                    ? 'md-notifications'
                    : 'ios-notifications'
                }
                color={color}
                size={27}
                style={{
                  marginLeft: -35
                }}
              />
            )
          }}
        />
        <Tab.Screen
          name="Förråd"
          component={ProductsScreen}
          options={{
            tabBarIcon: ({ color }) => (
              <MaterialIcons
                name={'file-download'}
                color={color}
                size={27}
                style={{
                  marginLeft: -70
                }}
              />
            )
          }}
        />
        <Tab.Screen
          name="Mitt Förråd"
          component={UserProductsScreen}
          options={{
            tabBarIcon: ({ color }) => (
              <MaterialIcons
                name={'file-upload'}
                color={color}
                size={30}
                style={{
                  marginRight: -70
                }}
              />
            )
          }}
        />
        <Tab.Screen
          name="Min Sida"
          component={UserSpotlightScreen}
          options={{
            tabBarBadge: 4,
            tabBarIcon: ({ color }) => (
              <FontAwesome
                name={'user'}
                color={color}
                size={30}
                style={{
                  marginRight: -35
                }}
              />
            )
          }}
        />
      </Tab.Navigator>
    </>
  );
};

export default ProductsOverviewScreen;
like image 173
Osa Gambas Avatar answered Mar 05 '23 14:03

Osa Gambas