react-native系列(15)导航篇:底部导航TabNavigator参数及使用详解

本篇主要介绍的是TabNavigator,假设你已经对它的用法已经有了基本的认识,或重新去官网看一下

官网地址:https://reactnavigation.org/zh-Hans/

底部导航TabNavigator的效果类似于微信,效果图:

TabNavigator生成的底部导航的结构,它包括4部分:

  • 选项卡栏
  • 选项卡
  • 图标
  • 标签文本

createBottomTabNavigator函数

使用createBottomTabNavigator函数来创建底部导航,它包括2个参数对象:第一个参数用来配置路由页面,第二个参数用来配置底部导航的信息,如样式等。

创建时,相关参数详解如下:

const rootTab = createBottomTabNavigator(
    {
        Page1: { screen: PageView1 },
        Page2: { screen: PageView2, params: {}} // 第二个参数params为页面入参
    },
    {
        initialRouteName: 'Page1', // 第一次加载时初始选项卡路由的 routeName
        order: ['Page1', 'Page2'], // 定义选项卡顺序的 routeNames 数组
        backBehavior: 'initialRoute', // 触发navigation.goBack()方法时是否包括Tab页间切换的的返回操作,不包括为none,包括为initialRoute(默认包括)
        // tabBarComponent : (props) => {return <BottomTabBar {...props} />}, // 可选,覆盖用作标签栏的组件,一般会用不上
        tabBarOptions: {
            activeTintColor: '', // 活动选项卡标签文本和图标颜色
            activeBackgroundColor: '', // 活动选项卡的背景色
            inactiveTintColor: '', // 非活动选项卡的标签文本和图标颜色
            inactiveBackgroundColor: '', // 非活动选项卡的背景色
            showLabel: true, // 是否显示选项卡的标签, 默认值为 true
            showIcon: false, // 是否显示 Tab 的图标,默认为false
            style: {}, // 选项卡栏的默认样式
            tabStyle: {}, // 选项卡的默认样式
            labelStyle: {}, // 选项卡标签文本的默认样式
            allowFontScaling: true // 允许标签字体自动缩放以对界面更友好,默认为: true
        },
        defaultNavigationOptions: ({ navigation }) => ({
            tabBarVisible: true, // true或false用于显示或隐藏标签栏,如果未设置,则默认为true
            // 选项卡 自定义图标
            tabBarIcon: ({ focused, horizontal, tintColor }) => {
                const { routeName } = navigation.state; // 选项卡名称
                console.log(focused); // 是否处于活动状态,是为true
                console.log(horizontal); // 是否处于横屏,是为true
                console.log(tintColor); // 状态颜色值
                return(
                    <View />
                );
            },
            // 选项卡 自定义标签文本
            tabBarLabel: ({focused, tintColor}) => {
                const { routeName } = navigation.state; // 选项卡名称
                console.log(focused); // 是否处于活动状态,是为true
                console.log(tintColor); // 状态颜色值
                return(
                    <View />
                );
            }
        })
    }
);

贴上完整代码:

import React, { Component } from 'react';
import { View, Text } from 'react-native';
import { HomeScreen, SettingsScreen } from './TabScreen';
import { createBottomTabNavigator, createAppContainer } from 'react-navigation';

const rootTab = createBottomTabNavigator(
    {
        Home: HomeScreen,
        Settings: SettingsScreen,
    },
    {
        initialRouteName: 'Home', // 第一次加载时初始选项卡路由的 routeName
        order: ['Home', 'Settings'], // 定义选项卡顺序的 routeNames 数组
        backBehavior: 'initialRoute', // 触发navigation.goBack()方法时是否包括Tab页间切换的的返回操作,不包括为none,包括为initialRoute(默认包括)
        // tabBarComponent : (props) => {return <BottomTabBar {...props} />}, // 可选,覆盖用作标签栏的组件,一般会用不上
        tabBarOptions: {
            activeTintColor: 'red', // 活动选项卡标签文本和图标颜色
            activeBackgroundColor: '#FFFFFF', // 活动选项卡的背景色
            inactiveTintColor: 'gray', // 非活动选项卡的标签文本和图标颜色
            inactiveBackgroundColor: '#FFFFFF', // 非活动选项卡的背景色
            showLabel: true, // 是否显示选项卡的标签, 默认值为 true
            showIcon: true, // 是否显示 Tab 的图标,默认为false
            // 选项卡栏的样式
            style: {
                borderTopColor: 'red',
                height: 50
            }, 
            // 选项卡的默认样式
            tabStyle: {
                flex: 1,
                justifyContent: 'center',
                alignItems: 'center'
            }, 
            // 选项卡标签文本的默认样式
            labelStyle: {
                fontSize: 14
            }, 
            allowFontScaling: true // 允许标签字体自动缩放以对界面更友好,默认为: true
        },
        defaultNavigationOptions: ({ navigation }) => ({
            tabBarVisible: true, // true或false用于显示或隐藏标签栏,如果未设置,则默认为true
            // 选项卡 默认自定义图标
            // eslint-disable-next-line
            tabBarIcon: ({ focused, horizontal, tintColor }) => {
                const { routeName } = navigation.state; // 选项卡名称
                console.log(focused); // 是否处于活动状态,是为true
                console.log(horizontal); // 是否处于横屏,是为true
                console.log(tintColor); // 状态颜色值
                let textStyle = {};
                if(focused){
                    textStyle = {
                        color: 'red'
                    };
                }
                return(
                    <View>
                        <Text style={textStyle}>{routeName}-Icon</Text>
                    </View>
                );
            },
            // 选项卡 默认自定义标签文本
            // eslint-disable-next-line
            // tabBarLabel: ({focused, tintColor}) => {
            //     const { routeName } = navigation.state; // 选项卡名称
            //     console.log(focused); // 是否处于活动状态,是为true
            //     console.log(tintColor); // 状态颜色值
            //     return(
            //         <View>
            //             <Text>{routeName}-Label</Text>
            //         </View>
            //     );
            // }
        })
    }
);
const AppNavigatorContainer  = createAppContainer(rootTab);

class TabNavigator extends Component {
    render(){
        return(
            <View style={{flex:1}}>
                <AppNavigatorContainer />
            </View>
        );
    }
}

export default TabNavigator;

上面代码的图标部分为了方便我用文本表示,这里建议用Image组件或引用Iconfont或svg图标。

另外,贴上其中一个Home页面代码:

import React from 'react';
import { Text, View, StyleSheet, TouchableOpacity } from 'react-native';
import PropTypes from 'prop-types';

class HomeScreen extends React.Component {
  render() {
    const { navigation } = this.props;
    return (
        <View style={styles.viewContainer}>
            <Text style={styles.contextTextStyle}>HomeScreen!</Text>
            <TouchableOpacity 
                style={styles.buttonContainer}
                onPress={()=>{navigation.navigate('Settings');}}
            >
                <Text>To SettingsScreen</Text>
            </TouchableOpacity>
        </View>
    );
  }
}

const styles = StyleSheet.create({
  viewContainer: {
      flex: 1, 
      alignItems: 'center', 
      justifyContent: 'center'
  },
  contextTextStyle: {
      fontSize: 30
  },
  buttonContainer: {
      backgroundColor: '#FFFFFF',
      borderRadius: 30,
      borderWidth: 1,
      height: 30,
      justifyContent: 'center',
      alignItems: 'center',
      padding: 5
  }
});

HomeScreen.propTypes = {
  navigation: PropTypes.object
};

export default HomeScreen;

效果:

如果参照微信的需求,还有一种情况就是需要知道当前有多少条信息,并有个红色的小图标显示在右上角。如果按照上面那种自定义默认图标的方法将无法实现,因为它无法获取Home页面的状态值。那如果我们可以在Hemo页面中也能实现自定义图标不就可以了吗?对的,只要在Home中定义一个静态navigationOptions函数即可,修改上面的Hoem页面代码如下:

import React from 'react';
import { Text, View, StyleSheet, TouchableOpacity } from 'react-native';
import PropTypes from 'prop-types';

class HomeScreen extends React.Component {
  static navigationOptions = ({ navigation }) => ({
    tabBarVisible: true, // true或false用于显示或隐藏标签栏,如果未设置,则默认为true
    // 选项卡 自定义图标
    // eslint-disable-next-line
    tabBarIcon: ({ focused, horizontal, tintColor }) => {
        const { routeName } = navigation.state; // 选项卡名称
        console.log(focused); // 是否处于活动状态,是为true
        console.log(horizontal); // 是否处于横屏,是为true
        console.log(tintColor); // 状态颜色值
        let textStyle = {};
        if(focused){
            textStyle = {
                color: 'red'
            };
        }
        return(
            <View>
                <Text style={textStyle}>{routeName}-Icon-信息({navigation.getParam('msg')})</Text>
            </View>
        );
    },
  })

  state = {
    msg: 100
  }

  componentDidMount() {
      this.props.navigation.setParams({ msg: this.state.msg });
  }

  render() {
    const { navigation } = this.props;
    return (
        <View style={styles.viewContainer}>
            <Text style={styles.contextTextStyle}>HomeScreen!</Text>
            <TouchableOpacity 
                style={styles.buttonContainer}
                onPress={()=>{navigation.navigate('Settings');}}
            >
                <Text>To SettingsScreen</Text>
            </TouchableOpacity>
        </View>
    );
  }
}

const styles = StyleSheet.create({
  viewContainer: {
      flex: 1, 
      alignItems: 'center', 
      justifyContent: 'center'
  },
  contextTextStyle: {
      fontSize: 30
  },
  buttonContainer: {
      backgroundColor: '#FFFFFF',
      borderRadius: 30,
      borderWidth: 1,
      height: 30,
      justifyContent: 'center',
      alignItems: 'center',
      padding: 5
  }
});

HomeScreen.propTypes = {
  navigation: PropTypes.object
};

export default HomeScreen;

效果:

  • 3
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值