【问题标题】:add notification counter badge on my react-navigation/material-bottom-tabs在我的 react-navigation/material-bottom-tabs 上添加通知计数器徽章
【发布时间】:2020-07-04 00:18:14
【问题描述】:

我想添加一个带有徽章的通知计数器,如下所示: t-native

这是我的 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>
  )}
;

这是 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;


这就是我在 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>
  );
}

所以我想将 app.js 中的 notificationCounter 编号传递到 MainTabScreen 我有底部标签的地方。

ps:我尝试使用钩子,但我无法获得任何价值

感谢您的帮助。

【问题讨论】:

    标签: reactjs react-native react-hooks


    【解决方案1】:

    您可以使用 materialBottomBar 上的tabBarBadge 选项在其上显示徽章。

    官方文档的链接是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} />
              ),
            }}
       />
    

    【讨论】:

    • 如果能解决您的问题,请点赞并接受我的回答
    • 你知道如何做条件标签栏徽章吗?就像用户有通知一样,呈现标签栏徽章,否则不?提前致谢
    • @kalculated tabBarBadge: badgeCount ? badgeCount : null 你可以像这样传递变量。 badgeCount 将存储您要显示的计数。
    • 请将@FerinPatel 的答案标记为答案——这正是我所需要的。谢谢!
    • @KevinWang 很高兴听到我的回答对您有所帮助。谢谢