2

I am trying to customize the colour of the material bottom tab navigator to LinearGradient.

To achieve this I am using expo- linear-gradient, and I am using props to pass the methods, but I don't know how to access these props in the customTabBar function.

Here is my code containing the tabs

import React from "react";
import { View, Text, StyleSheet, Image, ImageBackground } from "react-native";
import { createMaterialBottomTabNavigator } from "@react-navigation/material-bottom-tabs";

import MainHomeScreen from "./MainHomeScreen";
import CustomTabBar from "./CustomTabBar";

import * as Icons from "@expo/vector-icons";
import { LinearGradient } from "expo-linear-gradient";

const Tab = createMaterialBottomTabNavigator();

const BottomTabScreen = () => {
  return (
    <>
      <Tab.Navigator
        screenOptions={{ tabBarLabel: false }}
        barStyle={(props) => <CustomTabBar {...props} />}
      >
        <Tab.Screen
          name="MainHomeScreen"
          component={MainHomeScreen}
          options={{
            tabBarIcon: ({ focused }) => (
              <>
                <Icons.Feather name="home" color="#fff" size={24} />
              </>
            ),
          }}
        />
      </Tab.Navigator>
    </>
  );
};

export default BottomTabScreen;

const styles = StyleSheet.create({
  shadow: { elevation: 5 },
  dot: {
    width: 4,
    height: 4,
    borderRadius: 7,
    marginTop: 5,
    backgroundColor: "#fff",
  },
  linearGradient: {
    height: 30,
    width: 50,
  },
});

This is the code of the custom tab bar:

import React from "react";
import { View, Text, StyleSheet } from "react-native";

const CustomTabBar = ({ state, navigationState }) => {
  console.log(navigationState);
  return <View style={styles.tabs}>
    {state.route.map((route, index) => {
      
    })}
  </View>;
};

export default CustomTabBar;

const styles = StyleSheet.create({
  tabs: {
    position: "absolute",
    bottom: 15,
    left: 20,
    right: 20,
    elevation: 2,
    borderRadius: 20,
    backgroundColor: "transparent",
    borderTopLeftRadius: 15,
    borderTopRightRadius: 15,
    overflow: "hidden",
  },
});

Ayush Kumar
  • 494
  • 1
  • 6
  • 21

2 Answers2

2

CustomTabBar for createBottomTabNavigator

Your approach was correct. Check this Snack out for the implementation. You'll get an idea of how to achieve this.

After writing the below code just change the Gradient color arrays as desired.

Your BottomTabNavigator should look like this ....

import * as React from 'react';
import { View } from 'react-native';
import { useTheme } from '@react-navigation/native';
import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';

import CustomTabBar from '../components/CustomTapBar';
import ScreenOne from '../screens/ScreenOne';
import Favourites from '../screens/Favourites';

const Tab = createBottomTabNavigator();

function RootNavigation() {
  const { colors } = useTheme();

  return (
    <View style={{ flex: 1, backgroundColor: colors.background }}>
      <Tab.Navigator tabBar={(props) => <CustomTabBar {...props} />}>
        <Tab.Screen name="ScreenOne" component={ScreenOne} />
        <Tab.Screen name="Favourites" component={Favourites} />
      </Tab.Navigator>
    </View>
  );
}

export default RootNavigation;

Your CustomTabBar should look like this -

import React, { Component } from 'react';
import { View, Text, TouchableOpacity } from 'react-native';
import { LinearGradient } from 'expo-linear-gradient';

const FocusedGradient = ['#4c669f', '#3b5998', '#192f6a'];
const NotFocusedGradient = ['#ffffff', '#ffffff'];

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

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

  return (
    <View style={{ flexDirection: 'row' }}>
      {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);
          }
        };

        const onLongPress = () => {
          navigation.emit({
            type: 'tabLongPress',
            target: route.key,
          });
        };

        return (
          <LinearGradient
            colors={isFocused ? FocusedGradient : NotFocusedGradient}
            style={{
              flex: 1,
              backgroundColor: isFocused ? 'dodgerblue' : 'white',
            }}>
            <TouchableOpacity
              accessibilityRole="button"
              accessibilityState={isFocused ? { selected: true } : {}}
              accessibilityLabel={options.tabBarAccessibilityLabel}
              testID={options.tabBarTestID}
              onPress={onPress}
              onLongPress={onLongPress}
              style={{
                minHeight: 50,
                justifyContent: 'center',
                alignItems: 'center',
              }}>
              <Text style={{ color: isFocused ? 'white' : '#222' }}>
                {label}
              </Text>
            </TouchableOpacity>
          </LinearGradient>
        );
      })}
    </View>
  );
}

export default CustomTabBar;
Kartikey
  • 4,516
  • 4
  • 15
  • 40
0

To create a CustomTabBar in createBottomTabNavigator. Follow the below example using expo. createBottomTabNavigator (CustomTabBar)

enter image description here

Utonium
  • 474
  • 4
  • 10