一、 最简单的实现
前提:已配置好tabbar
1、效果
简单嵌套路由实现
2、安装依赖
"@react-navigation/stack": "^6.3.29",//栈导航(Stack Navigation)
"react-native-gesture-handler": "^2.17.1",// 手势支持
react-native-gesture-handler 需要在入口文件最顶部引入
3、页面层级
(1) Profile1Screen.jsx和Profile2Screen.jsx
两个页面
Profile1Screen.jsx
import { View,Button } from "react-native";
const Profile1Screen = ({navigation}) => {
return (
<View>
<Button title="go home" onPress={() => navigation.navigate("Home")} />
<Button title="go Profile2 " onPress={() => navigation.navigate("profile2")} />
</View>
);
};
export default Profile1Screen;
Profile2Screens.jsx
import { View, Button } from "react-native";
const Profile2Screen = ({ navigation }) => {
return (
<View>
<Button title="go home" onPress={() => navigation.navigate("Home")} />
<Button title="go Profile1" onPress={() => navigation.navigate("profile1")}/>
</View>
);
};
export default Profile2Screen;
(2) SatckNavigation.jsx
注册路由,父路由(home)在最上边
import HomeScreen from "../screens/HomeScreen";
import Profile1Screen from "../screens/Profile1Screen";
import Profile2Screen from "../screens/Profile2Screen";
import { createStackNavigator } from "@react-navigation/stack";
const Stack = createStackNavigator();
export default function StackNavigation() {
return (
<Stack.Navigator>
<Stack.Screen name="Home" component={HomeScreen} />
<Stack.Screen name="profile1" component={Profile1Screen} />
<Stack.Screen name="profile2" component={Profile2Screen} />
</Stack.Navigator>
);
}
(3) BottomNavigation.jsx
tabbar 路由 :需要引入刚才写的子路由
import React from "react";
import StackNavigation from "./StackNavigation";
import SettingScreen from "../screens/SettingScreen";
import MyScreen from "../screens/MyScreen";
import Ionicons from "react-native-vector-icons/Ionicons";
import { createBottomTabNavigator } from "@react-navigation/bottom-tabs";
const BottomTab = createBottomTabNavigator();
export default function BottomTabNavigator() {
return (
<BottomTab.Navigator
screenOptions={({ route }) => ({
tabBarIcon: ({ focused, color, size }) => {
let iconName;
if (route.name === "Home") {
iconName = focused ? "home" : "home-outline";
} else if (route.name === "Settings") {
iconName = focused ? "settings" : "settings-outline";
} else if (route.name == "My") {
iconName = focused ? "person-sharp" : "person-outline";
}
return <Ionicons name={iconName} size={size} color={color} />;
},
tabBarActiveTintColor: "tomato",
tabBarInactiveTintColor: "gray",
})}
>
<BottomTab.Screen name="Home" component={StackNavigation} />
<BottomTab.Screen name="Settings" component={SettingScreen} />
<BottomTab.Screen name="My" component={MyScreen} />
</BottomTab.Navigator>
);
}
(4) App.jsx
引入tabbar 组件
import React from "react";
import { NavigationContainer } from "@react-navigation/native";
import BottomTabNavigator from "./src/navigation/BottomTabNavigator";
function App() {
return (
<NavigationContainer>
<BottomTabNavigator />
</NavigationContainer>
);
}
export default App;
完成了,可以实现基本的路由跳转了。但是还存在问题:
HomeScreen嵌套的两个子页面 应该是打开一个单独的页面,没有下边tabbar和顶部Home的title
二、 完善版
reactnative嵌套路由
1、设定 子页面底部取消tabbar
方法:上边是让tabbar 包裹在stack外边 ,现在让stack包裹tabbar
修改BottomTabNavigation.jsx
......省略
-<BottomTab.Screen name="Home" component={StackNavigation} />
+<BottomTab.Screen name="Home" component={HomeScreen} />
<BottomTab.Screen name="Settings" component={SettingScreen} />
<BottomTab.Screen name="My" component={MyScreen} />
修改StackNavigation
<Stack.Navigator>
+<Stack.Screen name="BottomTabNavigator"component={BottomTabNavigator}/>
- <Stack.Screen name="Home" component={HomeScreen} />
<Stack.Screen name="profile1" component={Profile1Screen} />
<Stack.Screen name="profile2" component={Profile2Screen} />
</Stack.Navigator>
修改App.jsx
<NavigationContainer>
<StackNavigation />
</NavigationContainer>
此时效果
子路由单独页面
每个页面上边多了一个BottomTabNavigation的title
2、 删掉每个tabbar上边的title
步骤:
(1)隐藏每个tabbr的title
(2)把stackNavigation 的改成每个页面的title
(1)隐藏每个tabbr的title
BottomTabNavigator.jsx 里 screenOptions 添加headerShown: false,
(2)把stackNavigation 的改成每个页面的title
SatckjNavigation.jsx 引入方法
import { getFocusedRouteNameFromRoute } from "@react-navigation/native";
function getHeaderTitle(route) {
const routeName = getFocusedRouteNameFromRoute(route) ?? "Home";
switch (routeName) {
case "Home":
return "home";
case "Settings":
return "settings";
case "My":
return "my";
}
}
动态设定每个页面title