Border bottom on Bottom Navigation in React Native

2019-08-31 07:00发布

问题:

I am new to React Native. I am making a bottom navigation bar. I want to add border bottom when the tab is selected, like the picture below. According to the docs, the indicatorStyle is only applicable on Top Navigation. I am unsure on how to do it.

import {
  createBottomTabNavigator,
} from 'react-navigation';
import SettingsScreen from '../settings';
import rootStyles from '../../rootStyles';
const ICON_HOME = require('../../../assets/icon/home.png');
const ICON_USER = require('../../../assets/icon/user_selected.png');
const ICON_CURRENCY = require('../../../assets/icon/currency.png');


export default createBottomTabNavigator({
  HomeScreen: {
    screen: SettingsScreen,
  },
  SettingsScreen: {
    screen: SettingsScreen,
  },
  CurrencyScreen: {
    screen: SettingsScreen,
  },
}, {
  navigationOptions: ({ navigation }) => ({
    tabBarIcon: ({ tintColor }) => {
      const { routeName } = navigation.state;
      let icon;

      switch (routeName) {
        case 'HomeScreen':
          icon = ICON_HOME;
          break;
        case 'SettingsScreen':
          icon = ICON_USER;
          break;
        case 'CurrencyScreen':
          icon = ICON_CURRENCY;
          break;
        default: break;
      }

      return (
        <Image
          source={icon}
          style={{
            height: rootStyles.em(2),
            width: rootStyles.em(2),
            tintColor,
          }}
        />
      );
    },
  }),
  tabBarPosition: 'bottom',
  tabBarOptions: {
    showLabel: false,
    activeTintColor: rootStyles.PRIMARY_COLOR,
  },
  tabBarSelectedItemStyle: {
    borderBottomWidth: 2,
    borderBottomColor: 'red',
  },
});

回答1:

You can do a custom tab for bottomTabNavigator. I have one of these working on a project, take a look:

import {createBottomTabNavigator} from "react-navigation-tabs";
import { CustomTab } from '../../common/components';
...

    const Tabs = createBottomTabNavigator({
      Home: {
        screen: HomeStack,
      },
      Events: {
        screen: EventStack,
      },
      Templates:{
        screen: TemplateStack
      }
    }, {
      initialRouteName: 'Home',
      tabBarOptions: {
        activeTintColor: theme.palette.primaryColor,
      },
      tabBarComponent: CustomTab,
      tabBarPosition: 'bottom',
    });

and my CustomTab component:

import React, {PureComponent} from 'react'
import {View, TouchableWithoutFeedback, Text, StyleSheet} from 'react-native'
import I18N from "react-native-i18n";
import * as Animatable from 'react-native-animatable';
import theme from '../theme'
import {Icon} from './Icon'

class CustomTab extends PureComponent {

  constructor(){
    super()
    this.state = {
      routeNameSelected:'Home'
    }
  }

  getIconName(routeName){
    switch (routeName) {
      case 'EventInfoTab':
        return 'information-outline'
      case 'EventChannelTab':
        return 'play-box-outline'
      case 'EventCommentTab':
        return 'comment-text-outline'
      case 'Home':
        return 'home'
      case 'Events':
        return 'calendar-star'
      case 'Templates':
        return 'clipboard-text'
    }
  }

  onPressTab(routeName){
    this.props.jumpTo(routeName)
    this.setState({
      routeNameSelected:routeName
    })
  }

  render() {
    const {navigation} = this.props;
    const {routes} = navigation.state;
    return (
        <View style={styles.tabbar}>
          {routes && routes.map((route, index) => {
            return (
              <TouchableWithoutFeedback
                key={route.key}
                style={styles.tab}
                onPress={() => this.onPressTab(route.routeName)}
              >
                <View style={{minHeight:50, justifyContent:'center'}}>
                  {navigation.state.index===index &&
                  <Animatable.View animation="rubberBand" duration={1000} style={styles.tab}>
                    <Icon size={24} name={this.getIconName(route.routeName)} style={{ color: theme.palette.primaryColor }} />
                    <Text style={[styles.tabText,{color: theme.palette.primaryColor}]}>{I18N.t('tabs.'+route.routeName)}</Text>
                  </Animatable.View>
                  }
                  {navigation.state.index!==index &&
                  <View style={styles.tab}>
                    <Icon size={24} name={this.getIconName(route.routeName)} style={{ color: theme.palette.colors.titleColor }} />
                    <Text style={[styles.tabText,{color: theme.palette.colors.titleColor}]}>{I18N.t('tabs.'+route.routeName)}</Text>
                  </View>
                  }
                </View>
              </TouchableWithoutFeedback>
            );
          })}

        </View>
    )
  }
}

export {CustomTab}

Define a state for underlying tab and the view rendered according to this state on CustomTab component. Let me know if this is helpful for you.