Younes BOUCHAMA
Younes BOUCHAMA

Reputation: 21

add notification counter badge on my react-navigation/material-bottom-tabs

i want to add a notification counter with badge like this: t-native

this is my code for the MainTabScreen

import React from 'react';

import { createMaterialBottomTabNavigator } from '@react-navigation/material-bottom-tabs';
import { createStackNavigator } from '@react-navigation/stack';

import Icon from 'react-native-vector-icons/Ionicons';
import MaterialCommunityIcons from 'react-native-vector-icons/MaterialCommunityIcons';
import Ionicons from 'react-native-vector-icons/Ionicons';
import IconBadge from 'react-native-icon-badge'; 

import {useTheme} from 'react-native-paper';
import { View } from 'react-native-animatable';
import {Text} from 'react-native';

import HomeScreen    from '_screens/home';
import DetailsScreen from '_screens/details';
import ExploreScreen from '_screens/explore';
import ProfileScreen from '_screens/profile';
import EditProfileScreen from '_screens/editProfile';

import { UserNotification } from '_contexts/main';


const HomeStack = createStackNavigator();
const DetailsStack = createStackNavigator();
const ProfileStack = createStackNavigator();


const Tab = createMaterialBottomTabNavigator();

const MainTabScreen = () => (
    <Tab.Navigator
      initialRouteName="Home"
      activeColor="#fff"
    >
      <Tab.Screen
        name="Home"
        component={HomeStackScreen}
        options={{
          tabBarLabel: 'Home',
          tabBarColor: '#009387',
          tabBarIcon: ({ color }) => (
            <Icon name="ios-home" color={color} size={26} />
          ),
        }}
      />
      <Tab.Screen
        name="Notifications"
        component={DetailsStackScreen}
        options={{
          tabBarLabel: 'Updates',
          tabBarColor: '#1f65ff',
          tabBarIcon: ({ color }) => (
            <IconBadge
            MainElement={<Icon name='ios-notifications' size={26} color={color} />}

            BadgeElement={
              <UserNotification.Consumer>
              {
                data => { 
                  <Text style={{ color: 'white' }}>{ data.unreadMessagesCount }</Text>
                }
              }
              </UserNotification.Consumer>
            }

            Hidden={
              <UserNotification.Consumer>
              {
                data => {
                  console.log("UserNotification",data)

                  if( data.unreadMessagesCount === 0 || ! data.unreadMessagesCount){
                    console.log("UserNotification",data)
                    return true;
                  }
                  console.log("UserNotification",data)
                  return false;
                }
              }
              </UserNotification.Consumer>
              }
          />
          ),
        }}
      />
      <Tab.Screen
        name="Explore"
        component={ExploreScreen}
        options={{
          tabBarLabel: 'Explore',
          tabBarColor: '#d02860',
          tabBarIcon: ({ color }) => (
            <Icon name="ios-aperture" color={color} size={26} />
          ),
        }}
      />
      <Tab.Screen
        name="Profile"
        component={ProfileStackScreen}
        options={{
          tabBarLabel: 'Profile',
          tabBarColor: '#694fad',
          tabBarIcon: ({ color }) => (
            <Icon name="ios-person" color={color} size={26} />
          ),
        }}
      />
    </Tab.Navigator>
);

export default MainTabScreen;

const HomeStackScreen = ({navigation}) => (
<HomeStack.Navigator screenOptions={{
        headerStyle: {
        backgroundColor: '#009387',
        },
        headerTintColor: '#fff',
        headerTitleStyle: {
        fontWeight: 'bold'
        }
    }}>
        <HomeStack.Screen name="Home" component={HomeScreen} options={{
        title:'Overview',
        headerLeft: () => (
            <Icon.Button name="ios-menu" size={25} backgroundColor="#009387" onPress={() => navigation.openDrawer()}></Icon.Button>
        )
        }} />
</HomeStack.Navigator>
);

const DetailsStackScreen = ({navigation}) => (
  <DetailsStack.Navigator
    screenOptions={{
      headerStyle: {
        backgroundColor: '#1f65ff',
      },
      headerTintColor: '#fff',
      headerTitleStyle: {
        fontWeight: 'bold',
      },
    }}>
    <DetailsStack.Screen
      name="Details"
      component={DetailsScreen}
      options={{
        headerLeft: () => (
          <Icon.Button
            name="ios-menu"
            size={25}
            backgroundColor="#1f65ff"
            onPress={() => navigation.openDrawer()}
          />
        ),
      }}
    />
  </DetailsStack.Navigator>
);

const ProfileStackScreen = ({navigation}) => {
  const {colors} = useTheme();

  return (
  <ProfileStack.Navigator
    screenOptions={{
      headerStyle: {
        backgroundColor: colors.background,
        shadowColor: colors.background, // iOS
        elevation: 0, // Android
      },
      headerTintColor: colors.text,
    }}>
    <ProfileStack.Screen
      name="Profile"
      component={ProfileScreen}
      options={{
        title: '',
        headerLeft: () => (
          <View style={{marginLeft:10}}>
            <Icon.Button
              name="ios-menu"
              size={25}
              backgroundColor= {colors.background}
              color={colors.text}
              onPress={() => navigation.openDrawer()}
            />
          </View>
        ),
        headerRight: () => (
          <View style={{marginRight:10}}>
            <MaterialCommunityIcons.Button
              name="account-edit"
              size={25}
              backgroundColor= {colors.background}
              color={colors.text}
              onPress={() => navigation.navigate('EditProfile')}
            />
          </View>
        ),
      }}
    />
    <ProfileStack.Screen 
      name="EditProfile"
      options={{
        title: 'Edit Profile'
      }}
      component={EditProfileScreen}
    />
  </ProfileStack.Navigator>
  )}
;

this is a code for RootDrawerScreen

import React from 'react';

import { createDrawerNavigator } from '@react-navigation/drawer';

//Import all the screens needed
import MainTabScreen from '_navigations/bottomNav';
import SupportScreen from '_screens/support';
import SettingsScreen from '_screens/setting';
import BookmarkScreen from '_screens/bookmark';
import PostScreen from '_screens/post';
import CameraScreen from '_screens/camera';

import { DrawerContent } from '_screens/drawer';


const Drawer = createDrawerNavigator();

// specify screens where we need the drawer navigation
const RootDrawerScreen = ({navigation}) => (
    <Drawer.Navigator drawerContent={props => <DrawerContent {...props} />}>
        <Drawer.Screen name="HomeDrawer" component={MainTabScreen} screenProps={{ unreadMessagesCount: 8 }} />
        <Drawer.Screen name="SupportScreen" component={SupportScreen} />
        <Drawer.Screen name="SettingsScreen" component={SettingsScreen} />
        <Drawer.Screen name="BookmarkScreen" component={BookmarkScreen} />
        <Drawer.Screen name="PostScreen" component={PostScreen} />
        <Drawer.Screen name="CameraScreen" component={CameraScreen} />
    </Drawer.Navigator>
);

export default RootDrawerScreen;


and this what i have on app.js

const notificationCounter = {
  unreadMessagesCount: 8
}

return (
    <PaperProvider theme={theme}>
    <AuthContext.Provider value={authContext}>
      <UserContext.Provider value={loginState}>

      <NavigationContainer theme={theme} >
        { loginState.userToken !== null ? (
          <UserNotification.Provider value={notificationCounter}>
             <RootDrawerScreen />
          </UserNotification.Provider>

        )
      :
        <RootStackScreen/>
      }
      </NavigationContainer>
      </UserContext.Provider>
    </AuthContext.Provider>
    </PaperProvider>
  );
}

so i want to pass notificationCounter number from the app.js to MainTabScreen where i have the bottom tabs.

ps: i tried with hooks but i can't get any value

thanks for your help.

Upvotes: 2

Views: 12616

Answers (1)

Ferin Patel
Ferin Patel

Reputation: 3998

You can use tabBarBadge option on materialBottomBar to show badge on it.

Link to official docs is here

<Tab.Screen
        name="Home"
        component={HomeStackScreen}
        options={{
          tabBarLabel: 'Home',
          tabBarColor: '#009387',
          tabBarBadge: 5                          // This is for bar Badge
          tabBarIcon: ({ color }) => (
            <Icon name="ios-home" color={color} size={26} />
          ),
        }}
   />

Upvotes: 23

Related Questions