react-native 实现带icon的底部导航栏

一:需要的依赖包

yarn add react-navigation react-navigation-tabs react-navigation-stack react-native-gesture-handler react-native-gesture-handler  react-native-reanimated react-native-vector-icons --save

如果有安装失败的依赖包,就一个一个的安装。我在这边遇到一个react-native-vector-icons总是安装失败的问题,解决方法是把yarn add react-native -g后,再次安装就没问题了。

二:写页面

import { createStackNavigator } from 'react-navigation-stack';
import { createAppContainer, createSwitchNavigator } from 'react-navigation';
import { createBottomTabNavigator } from 'react-navigation-tabs';
import React, { Component } from 'react';
import { Platform, View, Text } from 'react-native';
// console.disableYellowBox = true; // 关闭全部黄色警告
import MaterialIcons from 'react-native-vector-icons/MaterialIcons';

class Page1 extends React.Component {
  render() {
    return (
      <View center', alignItems: 'center' }}>
        <Text>Home1!</Text>
      </View>
    );
  }
}
class Page2 extends React.Component {
  render() {
    return (
      <View center', alignItems: 'center' }}>
        <Text>Home2!</Text>
      </View>
    );
  }
}
class Page3 extends React.Component {
  render() {
    return (
      <View center', alignItems: 'center' }}>
        <Text>Home3!</Text>
      </View>
    );
  }
}
class Page4 extends React.Component {
  render() {
    return (
      <View center', alignItems: 'center' }}>
        <Text>Home4!</Text>
      </View>
    );
  }
}

export const BottomTab = createAppContainer(
  createBottomTabNavigator(
    {
      /*Page1路由*/
      Page1: {
        /*Page1页面*/
        screen: Page1,
        /*屏幕导航选项,可以定制导航器显示屏幕的方式(头部标题,选项卡标签等)*/
        navigationOptions: {
          /*导航标签名*/
          tabBarLabel: '页1',
          /*导航呈现的图标*/
          tabBarIcon: ({ tintColor, focused }) => (
            /*第三方图标库(图标名称,图标大小,图标样式*/
            <MaterialIcons name={'home'} size={26} style={{ color: tintColor }} />
          ),
          tabBarOnPress: (event) => {
            event.defaultHandler();//调用组建内默认的实现方法
            console.log('点击了某个tabBatBtn' + event);
          },
        },
      },
      Page2: {
        screen: Page2,
        navigationOptions: {
          tabBarLabel: '页2',
          tabBarIcon: ({ tintColor, focused }) => (
            <MaterialIcons
              name={'location-on'}
              size={26}
              style={{ color: tintColor }}
            />
          ),
          tabBarOnPress: (event) => {
            event.defaultHandler();//调用组建内默认的实现方法
            console.log('点击了某个tabBatBtn' + event);
          },
        },
      },
      Page3: {
        screen: Page3,
        navigationOptions: {
          tabBarLabel: '页3',
          tabBarOnPress: (event) => {
            event.defaultHandler();//调用组建内默认的实现方法
            console.log('点击了某个tabBatBtn' + event);
          },
        },
      },
      Page4: {
        screen: Page4,
        navigationOptions: {
          tabBarLabel: '页4',
          tabBarIcon: ({ tintColor, focused }) => (
            <MaterialIcons
              name={'perm-identity'}
              size={26}
              style={{ color: tintColor }}
            />
          ),
          tabBarOnPress: (event) => {
            event.defaultHandler();//调用组建内默认的实现方法
            console.log('点击了某个tabBatBtn' + event);
          },
        },
      },
    },
    {
      tabBarOptions: {
        /*设置活动选项卡标签的颜色*/
        activeTintColor: Platform.OS === 'ios' ? '#06C1AE' : '#06C1AE',
        // activeBackgroundColor: 'red',//活动选项卡的背景颜色。
        // inactiveTintColor: 'yellow',//非活动选项卡的标签和图标颜色。
        // inactiveBackgroundColor: 'pink',//非活动选项卡的背景颜色。

        // showLabel: true,//是否为标签显示标签,默认为true。
        showIcon: false,//是否显示选项卡的图标,默认为true。显示icon的话,labelStyle的的行高就要删掉

        // style: {},//标签栏的样式对象。
        labelStyle: {//选项卡标签的样式对象。
          fontSize: 16,
          lineHeight: 46 // style和tabStyle都找不到垂直居中的属性,只能设置行高。
        },
        tabStyle: {},//选项卡的样式对象。

        // allowFontScaling: true,//标签字体是否应缩放以符合“文本大小”辅助功能设置,默认为true。

        // //覆盖forceInset道具 < SafeAreaView >。
        // // 默认为{bottom:'always', top:'never'}。可用键top | bottom | left | right随值提供'always' | 'never'。
        safeAreaInset: {
          bottom: 'never',
          top: 'always'
        },
      },
    },
  ),
);

const AppRouter = createStackNavigator({
  Home: {
    screen: BottomTab,
    navigationOptions: {
      header: null, //可以通过将header设为null来禁用StackNavigator的Navigation
    },
  },
});

export const AppCreateNavigator = createAppContainer(
  createSwitchNavigator(
    {
      AppRouter: AppRouter,
    },
    {
      initialRouteName: 'AppRouter',
    },
  ),
);

export default class app extends React.Component {
  render() {
    return (
      <AppCreateNavigator />
    )
  }
}

注意点:1、设置icon时,labelStyle不要设置行高。没有图标并且想要文字垂直居中的话,要设置labelStyle的行高。

具体的配置见这里:React Navigation