ReactNative——导航器createBottomTabNavigator(底部标签导航器篇)

  • Post author:
  • Post category:其他


上一篇有讲到堆栈式导航器的写法,点这里->

堆栈式导航器


标签导航器官网链接

先安装依赖包

yarn add @react-navigation/bottom-tabs

接着在src/navigator文件夹下新建BottomTabs.tsx文件,写法跟堆栈式导航器类似的~

import React from 'react';
import { NavigationContainer } from '@/react-navigation/native';
import { createBottomTabNavigator } from '@/react-navigation/bottom-tabs'
import Home from '@/pages/Home';
import Listen from '@/pages/Listen';
import Found from '@/pages/Found';
import Account from '@/pages/Account';

export type BottomTabParamList = {
    Home:undefined;
    Listen:undefined;
    Found:undefined;
    Account:undefined;
}

const Tab = createBottomTabNavigator<BottomTabParamList>()

class BottomTabs extends React.Component {
    render() {
        return (
             <NavigationContainer>
                <Tab.Navigator>
                    <Tab.Screen name="Home" component={Home}/>
                    <Tab.Screen name="Listen" component={Listen}/>
                    <Tab.Screen name="Found" component={Found}/>
                    <Tab.Screen name="Account" component={Account}/>
                </Tab.Navigator>
            </NavigationContainer>
        )
    }    
}

export default BottomTabs;

然后在src/index.tsx使用该导航器

import Navigator from '@/navigator/BottomTabs';
 
export default Navigator;

如何更改为自定义的标签名字?

在options属性里修改

<NavigationContainer>
    <Tab.Navigator>
        <Tab.Screen 
            name="Home" 
            component={Home}
            options={{tabBarLabel:'首页'}}
        />
        <Tab.Screen
            name="Listen" 
            component={Listen} 
            options={{tabBarLabel:'我听'}}
        />
        <Tab.Screen 
            name="Found" 
            component={Found} 
            options={{tabBarLabel:'发现'}}
        />
        <Tab.Screen 
            name="Account" 
            component={Account} 
            options={{tabBarLabel:'我的'}}
        />
    </Tab.Navigator>
</NavigationContainer>

【改动后效果如下图】

如何更改标签选中的颜色?

使用tabBarOptions属性

<NavigationContainer>
    <Tab.Navigator 
        tabBarOptions={{
            activeTintColor:'#f86442',
        }}>
        <Tab.Screen 
            name="Home" 
            component={Home}
            options={{tabBarLabel:'首页'}}
        />
        <Tab.Screen
            name="Listen" 
            component={Listen} 
            options={{tabBarLabel:'我听'}}
        />
        <Tab.Screen 
            name="Found" 
            component={Found} 
            options={{tabBarLabel:'发现'}}
        />
        <Tab.Screen 
            name="Account" 
            component={Account} 
            options={{tabBarLabel:'我的'}}
        />
    </Tab.Navigator>
</NavigationContainer>

如果要实现在首页里点击某处跳转到详情页要怎么实现呢?这涉及到导肮嵌套

将堆栈式导航器嵌套到标签导航器

在首页里嵌套堆栈式导航器BottomTabs.tsx

import React from 'react';
import { NavigationContainer } from '@/react-navigation/native';
import { createBottomTabNavigator } from '@/react-navigation/bottom-tabs'
import Test from './index'; // 注意这里引入的是堆栈式导航器组件
import Listen from '@/pages/Listen';
import Found from '@/pages/Found';
import Account from '@/pages/Account';

export type BottomTabParamList = {
    Test:undefined; // 这里改一下
    Listen:undefined;
    Found:undefined;
    Account:undefined;
}

const Tab = createBottomTabNavigator<BottomTabParamList>()

class BottomTabs extends React.Component {
    render() {
        return (
             <NavigationContainer>
                <Tab.Navigator>
                    <Tab.Screen name="Test" component={Test}/>
                    <Tab.Screen name="Listen" component={Listen}/>
                    <Tab.Screen name="Found" component={Found}/>
                    <Tab.Screen name="Account" component={Account}/>
                </Tab.Navigator>
            </NavigationContainer>
        )
    }    
}

export default BottomTabs;

修改堆栈式导航器index.tsx(去掉NavigationContainer)

import React from 'react';
import {NavigationContainer} from '@react-navigation/native'
import {createStackNavigator} from '@react-navigation/stack'
import Home from '@/pages/Home';
import Detail from '@/pages/Detail';
import {
  createStackNavigator,
  StackNavigationProp,
} from '@react-navigation/stack'; // 自动引入
 
type RootStackPareamList = {
    Home: undefined; // 这里改一下
    Detail:undefined;
}
 
export type RootStackNavigation = StackNavigationProp<RootStackPareamList>
 
 
const Stack = createStackNavigator<RootStackPareamList>();
/*{
    Navigator, // 导航器
    Screen // 路由,也就是页面
}
*/
 
class Navigator extends React.Component {
    render(){
        return (
         <Stack.Navigator
            headerMode="float"
            screanOptions={{
                headerTitleAlign:'center',
            }}>
            <Stack.Screen 
                options={{ headerTitleAlign:'left, headerTitle:'首页'}} 
                name="Home" 
                component={Home}
            />
            <Stack.Screen name="Detail" component={Detail}/>
        </Stack.Navigator>);
    }
}
 
export default Navigator;

此时当在首页点击跳转详情页的时候,就能实现跳转了,下面的标签栏是不会消失的,如果想在跳转的时候底部导航器消失要怎么做呢?

将标签导航器嵌套到堆栈式导航器

修改标签导航器的代码问以下,去掉NavigationContainer

import React from 'react';
import { NavigationContainer } from '@/react-navigation/native';
import { createBottomTabNavigator } from '@/react-navigation/bottom-tabs'
import Home from '@/pages/Home'; // 注意这里改回为Home组件
import Listen from '@/pages/Listen';
import Found from '@/pages/Found';
import Account from '@/pages/Account';

export type BottomTabParamList = {
    Home:undefined;
    Listen:undefined;
    Found:undefined;
    Account:undefined;
}

const Tab = createBottomTabNavigator<BottomTabParamList>()

class BottomTabs extends React.Component {
    render() {
        return (
            <Tab.Navigator>
                <Tab.Screen name="Home" component={Home}/>
                <Tab.Screen name="Listen" component={Listen}/>
                <Tab.Screen name="Found" component={Found}/>
                <Tab.Screen name="Account" component={Account}/>
            </Tab.Navigator>
        )
    }    
}

export default BottomTabs;

将堆栈式导航器组件index.tsx还原到上一篇中的写法(即不要去掉NavigationContainer)

然后引入标签导航器

import React from 'react';
import {NavigationContainer} from '@react-navigation/native'
import {createStackNavigator} from '@react-navigation/stack'
// import Home from '@/pages/Home'; // 注意这里改成引入标签导航器了
import BottomTabs from './BottomTabs'; // 引入标签导航器
import Detail from '@/pages/Detail';
import {
  createStackNavigator,
  StackNavigationProp,
} from '@react-navigation/stack'; // 自动引入
 
type RootStackPareamList = {
    BottomTabs: undefined; // 这里改一下
    Detail:undefined;
}
 
export type RootStackNavigation = StackNavigationProp<RootStackPareamList>
 
const Stack = createStackNavigator<RootStackPareamList>();
/*{
    Navigator, // 导航器
    Screen // 路由,也就是页面
}
*/
 
class Navigator extends React.Component {
    render(){
        return (
            <NavigationContainer>
                <Stack.Navigator
                headerMode="float"
                screanOptions={{
                    headerTitleAlign:'center',
                }}>
                <Stack.Screen 
                    options={{ headerTitleAlign:'left, 
                    headerTitle:'首页'}} 
                    name="BottomTabs" 
                    component={BottomTabs}
                />
                <Stack.Screen name="Detail" component={Detail}/>
            </Stack.Navigator>);
    }
}
 
export default Navigator;

然后在src/index.tsx中修改为使用堆栈式导航器(因为是往堆栈式里嵌套了标签导航器,所以本质上其实是使用了堆栈式导航器为主体)

import Navigator from '@/navigator/index';
 
export default Navigator;

现在为止,就能实现跳转到详情页的时候,底部标签导航器消失了,

但是会有一个问题,当点击底部导航栏跳转的时候,标题总是显示首页,如下图所示

如何动态修改标题栏?

在BottomTabs.tsx中增加以下代码

import React from 'react';
import { NavigationContainer } from '@/react-navigation/native';
import { createBottomTabNavigator } from '@/react-navigation/bottom-tabs'
import Home from '@/pages/Home';
import Listen from '@/pages/Listen';
import Found from '@/pages/Found';
import Account from '@/pages/Account';

export type BottomTabParamList = {
    Home:undefined;
    Listen:undefined;
    Found:undefined;
    Account:undefined;
}

const Tab = createBottomTabNavigator<BottomTabParamList>() 

// 这里
type Route = RouteProp<RootStackParamList,'BottomTabs'>&
    state?:TabNavigationState;
}

// 这里
interface IProps {     
    navigation: RootStackNavigation;
    route:RouteProp<RootStackParamList,'BottomTabs'>;
}

// 增加一个获取标题名称的方法
function getHeaderTitle(route: Route) {
    const roureName = route.state
        ? route.state.routes[route.state.index].name
        : route.params?.screen || 'Home';
        switch(routeName) {
            case 'Home':
                return '首页';
            case 'Listen':
                return '我听';
            case 'Found':
                return '发现';
            case 'Account':
                return '账户';
            default:
                return '首页'
        }
}

class BottomTabs extends React.Component<IProps>{
    // props发生变化就会执行生命周期
    componentDidUpdate() {
        const {navigation,route} = this.props;
        navigation.setOptions({
            headerTitle:getHeaderTitle(route),
        });
    }

    render() {
        return (
            <Tab.Navigator>
                <Tab.Screen name="Home" component={Home}/>
                <Tab.Screen name="Listen" component={Listen}/>
                <Tab.Screen name="Found" component={Found}/>
                <Tab.Screen name="Account" component={Account}/>
            </Tab.Navigator>
        )
    }    
}

export default BottomTabs;

在index.tsx(堆栈式导航器)中增加以下代码

import React from 'react';
import {NavigationContainer} from '@react-navigation/native'
import {createStackNavigator} from '@react-navigation/stack'
import BottomTabs from './BottomTabs';
import Detail from '@/pages/Detail';
import {
  createStackNavigator,
  StackNavigationProp,
} from '@react-navigation/stack'; // 自动引入
 
type RootStackPareamList = {
    BottomTabs: { // 这里改一下
        screen?: string;    
    }; 
    Detail:undefined;
}
 
export type RootStackNavigation = StackNavigationProp<RootStackPareamList>
 
const Stack = createStackNavigator<RootStackPareamList>();

class Navigator extends React.Component {
    render(){
        return (
            <NavigationContainer>
                <Stack.Navigator
                headerMode="float"
                screanOptions={{
                    headerTitleAlign:'center',
                }}>
                <Stack.Screen 
                    // options={{headerTitle:'首页'}} 删掉这个属性,因为需要动态修改
                    name="BottomTabs" 
                    component={BottomTabs}
                />
                <Stack.Screen name="Detail" component={Detail}/>
            </Stack.Navigator>);
    }
}
 
export default Navigator;

效果如下



版权声明:本文为qq_37117521原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。