上一篇有讲到堆栈式导航器的写法,点这里->堆栈式导航器
标签导航器官网链接
先安装依赖包
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;
效果如下