react-navigation导航器
安装
- yarn add @react-navigation/native 这个是导航库,并且还需要安装下方依赖库
- yarn add react-native-screens react-native-safe-area-context
安装堆栈式导航
yarn add @react-navigation/native-stack
配置环境
- react-native-screens包需要一个额外的配置步骤才能在Android设备上正常工作。编辑MainActivity.java文件,该文件位于android/app/src/main/java/<你的包名>/MainActivity.java。 将以下代码添加到MainActivity类的主体:
并确保在包语句下面的文件顶部添加以下import语句:@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(null); }
import android.os.Bundle;
- 重启项目
使用堆栈式导航
- 首先需要从
@react-navigation/native
导出NavigationContainer
这个是导航的容器 - 从
@react-navigation/native-stack
导出createNativeStackNavigator
这个是堆栈导航,并且将这个堆栈导航赋值给Stack 从Stack中拿出 Navigator相当React-router中的Routes作为包裹,再** 从Stack中拿出Screen**作为路由 - Navigator组件属性
- 每一个Navigator组件的属性有 screenOptions 是一个对象可以统一设置路由的属性,包含名称,对其方式和样式等 Screen组件上也有一个一样的属性options其作用相同
import React, { Component } from "react"; import { NavigationContainer } from "@react-navigation/native"; import { createNativeStackNavigator } from '@react-navigation/native-stack'; import Home from "@/Home"; import Test from "@/Test"; type RootStackParamList = { Home: undefined, Test: undefined } // 堆栈导航器 const Stack = createNativeStackNavigator<RootStackParamList>(); class Navigator extends Component { render() { return ( <NavigationContainer> <Stack.Navigator> <Stack.Screen options={{ headerTitleAlign: 'center', headerTitle: '测试页' }} name="Test" component={Test} /> <Stack.Screen options={{ headerTitleAlign: 'center', headerTitle: '首页' }} name="Home" component={Home} /> </Stack.Navigator> </NavigationContainer> ); } } export default Navigator
- 在App.tsx中临时使用
import Navigator from "@/navigator"; export default Navigator
页面跳转
- const routes = useNavigationState(state => state.routes[0]); 函数式获取路由信息
- 类组件中可以直接从中this.props解构出**navigation **这个跳转函数
import React, { Component } from "react"; import { Button, Text, View } from "react-native"; class Home extends Component<any, any> { _onPress = () => { const { navigation } = this.props // 第一个参数是跳转的页面名称也是上方Stack.Screen的name名称, // 第二个参数是跳转传递的参数 navigation.navigate('Test',{ id: 100 }) } render() { return ( <View> <Text>Home</Text> <Button title="跳转Test页面" onPress={this._onPress} /> </View> ) } } export default Home;
底部标签导航器
yarn add @react-navigation/bottom-tabs
使用方式
import React, { Component } from "react";
import { NavigationContainer } from "@react-navigation/native";
import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
const Tab = createBottomTabNavigator();
import Des from "@/view/Des";
import My from "@/view/My";
class BottomTab extends Component {
render() {
return (
<NavigationContainer>
<Tab.Navigator>
<Tab.Screen name="Des" component={Des} />
<Tab.Screen name="My" component={My} />
</Tab.Navigator>
</NavigationContainer>
);
}
}
export default BottomTab;
App.tsx 导入
import BottomTab from "@/navigator/BottomTab";
export default BottomTab
顶部标签导航器
安装
yarn add @react-navigation/material-top-tabs react-native-tab-view
yarn add react-native-pager-view
- 使用方式和上方的都大体相同
导航器嵌套
两种方式:第一种方式堆栈式导航器嵌套标签导航器,第二种方式底部标签导航器嵌套堆栈式导航器
堆栈式导航器包含底部标签式导航器
嵌套导航器时,被包裹的那个导航器不需要NavigationContainer组件进行包裹
这种方式达到的效果是,当从一个页面跳转到另一个页面时,底部导航器是不存在的,例如详情页是不展示底部导航器的
但是这个导航器有个缺点,点击底部导航,顶部title不会改变需要处理下面的代码是处理的结果
- 堆栈式导航器中
import React, { Component } from "react"; import { NavigationContainer } from "@react-navigation/native"; import { createNativeStackNavigator } from "@react-navigation/native-stack"; import Test from "@/view/Test"; import Detail from "@/view/detail"; // 导入堆栈式导航器 import BottomTab from "./BottomTab"; // 堆栈导航器 const Stack = createNativeStackNavigator(); class Navigator extends Component { render() { return ( <NavigationContainer> <Stack.Navigator screenOptions={{ headerTitleAlign: "center", presentation: "card", animationTypeForReplace: "pop", animation: "slide_from_right", headerStyle: { backgroundColor: "red" }, headerShadowVisible: false, headerTintColor: "#fff" }}> // 将第一个页面作为底部标签导航器的容器 <Stack.Screen options={{ headerTitle: "首页" }} name="BottomTab" component={BottomTab} /> <Stack.Screen options={{ headerTitle: "测试页" }} name="Test" component={Test} /> <Stack.Screen name="Detail" component={Detail} /> </Stack.Navigator> </NavigationContainer> ); } } export default Navigator;
- 底部标签导航器BottomTab.tsx
import React, { useEffect } from "react"; import { createBottomTabNavigator } from "@react-navigation/bottom-tabs"; const Tab = createBottomTabNavigator(); import Des from "@/view/Des"; import My from "@/view/My"; import { useNavigation, useNavigationState } from "@react-navigation/native"; const BottomTab = () => { const nav = useNavigation(); // 获取路由数据 const routes = useNavigationState(state => state.routes[0]); const getHeaderTitle = () => { // @ts-ignore switch (routes.state && routes.state.routeNames[routes.state.index]) { case 'Des': return '描述' case 'My': return '我的' default: return '描述' } }; useEffect(() => { nav.setOptions({ headerTitle: getHeaderTitle() }); }, [routes]); return ( <Tab.Navigator screenOptions={{ tabBarActiveTintColor: "red", tabBarInactiveTintColor: "blue", headerShown: false }}> <Tab.Screen options={{ tabBarLabel: "详情" }} name="Des" component={Des} /> <Tab.Screen options={{ tabBarLabel: "我的" }} name="My" component={My} /> </Tab.Navigator> ); }; export default BottomTab;
20230126_190352_eFI77WmBeG
底部标签式导航器包裹堆栈式导航器
这个种方式无论跳转到哪个页面都会展示底部标签式导航器
- 底部标签式导航器中
import React, { Component } from "react"; import { NavigationContainer } from "@react-navigation/native"; import { createBottomTabNavigator } from '@react-navigation/bottom-tabs'; const Tab = createBottomTabNavigator(); import Des from "@/view/Des"; import My from "@/view/My"; // 导入堆栈式导航器 import Navigator from './index' class BottomTab extends Component { render() { return ( <NavigationContainer> <Tab.Navigator screenOptions={{ tabBarActiveTintColor: 'red', tabBarInactiveTintColor: 'blue' }}> { // 将第一个页面作为堆栈式导航的导航页 } <Tab.Screen name="Navigator" component={Navigator} /> <Tab.Screen options={{ tabBarLabel: '详情'}} name="Des" component={Des} /> <Tab.Screen options={{ tabBarLabel: '我的' }} name="My" component={My} /> </Tab.Navigator> </NavigationContainer> ); } } export default BottomTab;
- 底部标签式导航页,这里不需要使用NavigationContainer组件嵌套
import React, { Component } from "react"; import { createNativeStackNavigator } from "@react-navigation/native-stack"; import Home from "@/view/Home"; import Test from "@/view/Test"; import Detail from "@/view/detail"; // 堆栈导航器 const Stack = createNativeStackNavigator(); class Navigator extends Component { render() { return ( <Stack.Navigator screenOptions={{ headerTitleAlign: "center", presentation: "card", animationTypeForReplace: "pop", animation: "slide_from_right", headerStyle: { backgroundColor: "red" }, headerShadowVisible: false, headerTintColor: "#fff" }}> <Stack.Screen options={{ headerTitle: "首页" }} name="Home" component={Home} /> <Stack.Screen options={{ headerTitle: "测试页" }} name="Test" component={Test} /> <Stack.Screen name="Detail" component={Detail} /> </Stack.Navigator> ); } } export default Navigator;
20230126_191456_rLCtuedt73