StackNavigator -用于实现各个页面之间的跳转: 一次只渲染一个页面,并提供页面之间跳转的方法。 当打开一个新的页面时,它被放置在堆栈的顶部
TabNavigator - 渲染一个选项卡,让用户可以在几个页面之间切换
DrawerNavigator - 提供一个从屏幕左侧滑入的抽屉效果
yarn add @react-navigation/native
安装
npm install @react-navigation/native-stack
例子
// In App.js in a new project
import * as React from 'react';
import { View, Text } from 'react-native';
import { NavigationContainer } from '@react-navigation/native';
import { createNativeStackNavigator } from '@react-navigation/native-stack';
function HomeScreen() {
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Text>Home Screen</Text>
</View>
);
}
function DetailsScreen() {
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Text>Details Screen</Text>
</View>
);
}
const Stack = createNativeStackNavigator();
function App() {
return (
<NavigationContainer>
// initialRouteName指定堆栈的初始路由
// screenOptions 所有页面的公共样式可以写在里面
<Stack.Navigator initialRouteName="Home"
screenOptions={{
headerBackTitleVisible: false, //返回按钮标题是否可见(ios)
headerStyle: { shadowColor: "#FFFFFF", elevation: 0 },
headerTitleAlign: "center",
headerTitleStyle: { fontSize: 18, color: "#333333", fontStyle: "normal", fontWeight: "normal", textDecorationStyle: "solid" },
headerBackImage: () => {
// 自定义组件 返回按钮
return <Image style={{ marginLeft: Platform.OS == 'android' ? 0 : 12, marginRight: 20 }} source={require("@expo/snack-static/react-native-logo.png")} />
}
}}
mode="modal"
headerMode="float" // 头部保持在顶部
>
<Stack.Screen
name="Home"
component={HomeScreen}
options={{
title: '首页', //在头部中呈现标题
headerStyle: { // 样式对象,设置header背景等
backgroundColor: '#F3F3F3',
shadowColor: "#F3F3F3", elevation: 0
},
headerTintColor: '#fff', // 后退按钮和title使用这个颜色
headerTitleStyle: { // title文本的样式
fontWeight: 'bold',
},
}}
/>
<Stack.Screen name="Details" component={DetailsScreen} />
</Stack.Navigator>
</NavigationContainer>
);
}
export default App;
跳转路由
navigation.navigate('Details') // 如果路由还未在堆栈中,添加到堆栈并跳转路由;如果已经在当前路由上,再次跳转到这个路由,将什么都不会做。
navigation.push('Details') // 每次都会向导航堆栈添加一个新路由
navigation.goBack() // 回到上一个页面
navigation.popToTop() // 返回到堆栈中的第一个屏幕
向路由传递参数
navigation.navigate('Details',
{
itemId: 86,
otherParam: 'anything you want here',
});
// 获取参数
const { itemId, otherParam } = route.params;
// 更新参数
navigation.setParams({
query: 'someText',
});
向嵌套导航器传递参数
navigation.navigate('Account', {
screen: 'Settings',
params: { user: 'jane' },
});
使用navigation.setOptions
来定义header按钮
props.navigation.setOptions({
style: {
backgroundColor: "#F3F3F3"
},
headerRight: () => (
<Text
style={{
paddingHorizontal: 12,
color: "#BF9D4C",
fontSize: 15,
height: 50,
lineHeight: 50
}}
onPress={() => { callback && callback() }}
>{text}</Text>
),
});
嵌套导航跳转页面
function Root() {
return (
<Drawer.Navigator>
<Drawer.Screen name="Home" component={Home} />
<Drawer.Screen name="Profile" component={Profile} />
<Stack.Screen name="Settings" component={Settings} />
</Drawer.Navigator>
);
}
function App() {
return (
<NavigationContainer>
<Stack.Navigator>
<Stack.Screen
name="Root"
component={Root}
options={{ headerShown: false }}
/>
<Stack.Screen name="Feed" component={Settings} />
</Stack.Navigator>
</NavigationContainer>
);
}
从Feed组件跳转到Root组件
navigation.navigate('Root', { screen: 'Profile' });
在嵌套导航器中向屏幕传递参数
navigation.navigate('Root', {
screen: 'Profile',
params: { user: 'jane' },
});
导航的生命周期
假设在 stack navigator 中有,页面A,页面B。
进入页面A,调用 A.componentDidMount
进入页面B,调用 B.componentDidMount
离开页面B,调用 B.componentWillUnmount
离开页面A,调用 A.componentWillUnmount
实例场景
考虑一个带有屏幕a和b的堆栈导航器。在导航到a之后,它的componentDidMount被调用。当push B时,它的componentDidMount也被调用,但A仍然挂载在堆栈上,因此它的componentWillUnmount不被调用。
当从B返回到A时,B的componentWillUnmount被调用,但A的componentDidMount不被调用,因为A一直处于挂载状态。
安装
npm install @react-navigation/bottom-tabs
例子
import * as React from 'react';
import { Text, View } from 'react-native';
import { NavigationContainer } from '@react-navigation/native';
import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
function HomeScreen() {
return (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<Text>Home!</Text>
</View>
);
}
function SettingsScreen() {
return (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<Text>Settings!</Text>
</View>
);
}
const Tab = createBottomTabNavigator();
export default function App() {
return (
<NavigationContainer
screenOptions={({ route }) => ({
tabBarIcon: ({ focused, color, size }) => { //底部标签导航器icon
let iconName;
if (route.name === 'Home') {
iconName = focused
? 'ios-information-circle'
: 'ios-information-circle-outline';
} else if (route.name === 'Settings') {
iconName = focused ? 'ios-list-box' : 'ios-list';
}
// You can return any component that you like here!
return <Ionicons name={iconName} size={size} color={color} />;
},
tabBarActiveTintColor: 'tomato', // 活动的颜色
tabBarInactiveTintColor: 'gray', // 不活动的颜色
})}
>
<Tab.Navigator>
// tabBarBadge 给icons添加徽章
<Tab.Screen name="Home" component={HomeScreen} options={{ tabBarBadge: 3 }}/>
<Tab.Screen name="Settings" component={SettingsScreen} />
</Tab.Navigator>
</NavigationContainer>
);
}
tab之间跳转
从一个tab跳转到另一个tab,也是使用 navigation.navigate
navigation.navigate('Home')
安装
npm install @react-navigation/drawer
基于drawer的实例
import * as React from 'react';
import { Button, View } from 'react-native';
import { createDrawerNavigator } from '@react-navigation/drawer';
import { NavigationContainer } from '@react-navigation/native';
function HomeScreen({ navigation }) {
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Button
onPress={() => navigation.navigate('Notifications')}
title="Go to notifications"
/>
</View>
);
}
function NotificationsScreen({ navigation }) {
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Button onPress={() => navigation.goBack()} title="Go back home" />
</View>
);
}
const Drawer = createDrawerNavigator();
export default function App() {
return (
<NavigationContainer>
<Drawer.Navigator initialRouteName="Home">
<Drawer.Screen name="Home" component={HomeScreen} />
<Drawer.Screen name="Notifications" component={NotificationsScreen} />
</Drawer.Navigator>
</NavigationContainer>
);
}
打开和关闭drawer
navigation.openDrawer();
navigation.closeDrawer();
切换drawer
navigation.toggleDrawer();