【问题标题】:How to add badge to tab-bar in react-native?如何在 react-native 中将徽章添加到标签栏?
【发布时间】:2019-12-04 07:41:40
【问题描述】:

我正在使用 tabnavigator (createbottomBottomTabNavigator),需要帮助使用 redux 进行 bage 计数。

【问题讨论】:

    标签: react-native redux react-redux react-native-navigation


    【解决方案1】:

    您始终可以创建自定义组件,在本例中为选项卡项 (<TabBarItem />)。

    我创建了一个简单的演示,这里是小吃链接:https://snack.expo.io/@abranhe/tab-badge-count-redux

    在此示例中,您有 3 个页面/选项卡(应用程序、导航和配置文件),因此您需要管理每个页面/选项卡的通知计数器。所以我们从创建组件开始,我使用Native Base 来预构建组件。此外,我们还有以下初始状态。

    export default {
      apps: {
        notificationCount: 7,
      },
      navigation: {
        notificationCount: 0,
      },
      profile: {
        notificationCount: 3,
      },
    };
    
    

    TabBarItem.js

    import React from 'react';
    import { connect } from 'react-redux';
    import { View, StyleSheet } from 'react-native';
    import { Badge, Button, Icon, Text } from 'native-base';
    
    const renderBadge = ({ badgeProps, counter }) => (
      <Badge {...badgeProps} style={styles.badge}>
        <Text style={styles.notificationText}>{counter}</Text>
      </Badge>
    );
    
    function TabBarItem({ notificationCount, badgeProps, icon, label, color }) {
      let counter = 0;
    
      switch (icon) {
        case 'apps':
          counter = notificationCount.apps;
          break;
        case 'navigate':
          counter = notificationCount.navigation;
          break;
        case 'person':
          counter = notificationCount.profile;
          break;
        default:
          counter = 0;
      }
    
      return (
        <View style={styles.container}>
          {counter > 0 && renderBadge({ counter, badgeProps })}
          <View style={styles.iconContainer}>
            <Icon name={icon} style={{ color }} />
            <Text style={{ color, ...styles.label }}>{label}</Text>
          </View>
        </View>
      );
    }
    
    const styles = ....;
    
    const mapStateToProps = state => ({
      notificationCount: {
        apps: state.apps.notificationCount,
        navigation: state.navigation.notificationCount,
        profile: state.profile.notificationCount,
      },
    });
    
    export default connect(mapStateToProps)(TabBarItem);
    
    

    这只是一种解决方法,正如你所见,我正在创建一个连接到 Redux 的组件,并根据图标名称属性检查应该呈现哪个选项卡。如果我们只有一个带有通知的选项卡,那么我们只需要访问 Redux 上的数据,并自动呈现。

    我们需要创建一个reducer来处理增量和减量动作

    export default function reducer(state = initialState, action = {}) {
      switch (action.type) {
        case 'APPS.INCREMENT':
          return {
            ...state,
            apps: {
              ...state.apps,
              notificationCount: state.apps.notificationCount + 1,
            },
          };
    
        case 'APPS.DECREMENT':
          return {
            ...state,
            apps: {
              ...state.apps,
              notificationCount: state.apps.notificationCount - 1,
            },
          };
      ...
    }
    

    我们还需要添加创建的组件:

    import React from 'react';
    import { connect } from 'react-redux';
    import { StyleSheet } from 'react-native';
    import { Container, Content, H1, H3 } from 'native-base';
    import NotificationCounter from '../components/NotificationCounter';
    
    const Apps = ({ notificationCount, dispatch }) => (
      <Container>
        <Content contentContainerStyle={styles.container}>
          <H1>Apps Page</H1>
          <NotificationCounter
            handleIncrement={() => dispatch({ type: 'APPS.INCREMENT' })}
            handleDecrement={() => dispatch({ type: 'APPS.DECREMENT' })}
          />
          <H3>Notification Count: {notificationCount}</H3>
        </Content>
      </Container>
    );
    
    const styles = ...
    
    const mapStateToProps = state => ({
      notificationCount: state.apps.notificationCount,
    });
    
    export default connect(mapStateToProps)(Apps);
    

    我们正在使用dispatch({ type: 'APPS.INCREMENT' }) 来触发增加应用标签通知的操作。

    &lt;NotificationCounter /&gt; 组件代码:

    import React from 'react';
    import { View, StyleSheet } from 'react-native';
    import { Button, Text } from 'native-base';
    
    export default ({ handleDecrement, handleIncrement }) => (
      <View style={styles.container}>
        <Button onPress={handleDecrement}>
          <Text>Decrement</Text>
        </Button>
        <Button onPress={handleIncrement}>
          <Text>Increment</Text>
        </Button>
      </View>
    );
    
    const styles = ...
    

    【讨论】:

      【解决方案2】:

      有使用 redux 的自定义方法,您可以使用相同的方法制作自定义组件:-

      screen: NotificationScreen,
          navigationOptions: {
            tabBar: (state, acc) => ({
              icon: ({ tintColor, focused }) => (
                <BadgeTabIcon
                  iconName="notification"
                  size={26}
                  selected={focused}
                />
              ),
              visible: (acc && acc.visible !== 'undefined') ? acc.visible : true,
            }),
          },
        },
      

      在哪里,

      export default connect(state => ({
        notificationCount: state.notifications.count,
      }))(({ dispatch, nav }) => (
        <View>
          <TabIcon {...props} />
          {
            props.notificationCount > 0 ?
              <View style={{ position: 'absolute', right: 10, top: 5, backgroundColor: 'red', borderRadius: 9, width: 18, height: 18, justifyContent: 'center', alignItems: 'center' }}>
                <Text style={{ color: 'white' }}>{props.notificationCount}</Text>
              </View> : null
          }
        </View>
      ));
      

      阅读这里more

      另外,react native 中的官方 tabnavigation 也有同样的支持,你可以阅读heremore

      我希望这会有所帮助...谢谢:)

      【讨论】:

        猜你喜欢
        • 2019-08-31
        • 2018-10-31
        • 1970-01-01
        • 1970-01-01
        • 2013-12-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多