一、简介
React Navigation是React Native是目前最主流的屏幕页面切换的导航方案。React Navigation 5.x版本是目前最新的稳定版本,相对于老版本的配置方式更接近React Router,更好理解。
reactNative0.60.0以上的版本会省去很多配置,建议使用0.6以上版本
npx react-native init demo --version 0.60.0 //版本号自行定义
二、依赖安装
// 安装react-navigation
yarn add @react-navigation/native
// 安装依赖库
yarn add react-native-gesture-handler react-native-reanimated react-native-screens react-native-safe-area-context @react-native-community/masked-view
注意:链接原生库(0.60版本以上的跳过此步骤) React Native 0.60及更高版本开始,会自动链接,如果你版本是0.60及以上,这一步就可以跳过;而React Native 0.59以及更低版本则需要手动链接,安装react-native link。
react-native link react-native-reanimated
react-native link react-native-gesture-handler
react-native link react-native-screens
react-native link react-native-safe-area-context
安装navigator库 有三种导航模式可以选,分别是StackNavigator栈导航、TabNavigator标签导航、DrawerNavigator抽屉导航,下面会分别说一下怎么使用。
//StackNavigator
npm install @react-navigation/stack
//TabNavigator
npm install @react-navigation/bottom-tabs
//DrawerNavigator
npm install @react-navigation/drawer
三、StackNavigator导航
1使用教程:
1.引入组件
import { NavigationContainer } from '@react-navigation/native';
import { createStackNavigator } from '@react-navigation/stack';
2.创建栈导航 createStackNavigator提供APP屏幕之间切换的能力,它是以栈的形式来管理屏幕之间的切换,新切换到的屏幕会放在栈的顶部。
const Stack = createStackNavigator();
3.将需要进行屏幕切换的组件放入栈导航里
function App() {
return (
<NavigationContainer>
<Stack.Navigator>
<Stack.Screen name="Home" component={HomeScreen} />
</Stack.Navigator>
</NavigationContainer>
);
}
4.完整代码
app/views/LoginScreen.js
import React, { Component } from 'react';
import { View, Text, TouchableOpacity, StyleSheet } from 'react-native';
export default class HomeScreen extends Component {
constructor(props) {
super(props);
}
render() {
return (
<View>
<TouchableOpacity onPress={() => this.props.navigation.navigate('Home')}>
<Text >跳转首页</Text>
</TouchableOpacity>
</View>
)
}
}
app/views/HomeScreen.js
import React, { Component } from 'react';
import { View, Text, TouchableOpacity, StyleSheet } from 'react-native';
export default class HomeScreen extends Component {
constructor(props) {
super(props);
}
render() {
return (
<View>
<TouchableOpacity onPress={() => this.props.navigation.navigate('Login')}>
<Text >跳转登陆</Text>
</TouchableOpacity>
</View>
)
}
}
App.js
import 'react-native-gesture-handler';
import React, { Component } from 'react';
import { NavigationContainer } from '@react-navigation/native';
import { createStackNavigator } from '@react-navigation/stack';
//引入页面模块
import LoginScreen from './app/views/LoginScreen';
import HomeScreen from './app/views/HomeScreen';
const Stack = createStackNavigator();
function App() {
return (
<NavigationContainer>
<Stack.Navigator>
<Stack.Screen name="Login" component={LoginScreen} />
<Stack.Screen name="Home" component={HomeScreen} />
</Stack.Navigator>
</NavigationContainer>
);
}
export default App;
详细参数与配置说明
- Stack.Navigator的配置选项
- initialRouteName 首次加载名称
- screenOptions 屏幕的默认选项。如下示例。
<Stack.Navigator
initialRouteName="Page1" //作为初始化页面、不写的话默认第一个screen为初始化页面
screenOptions={{ //用来定制头部信息、根据自己需要更改
title: '测试标题',
headerStyle: {
backgroundColor: '#ee7530'
},
headerTintColor: '#fff',
headerTitleStyle: {
fontWeight: 'bold',
fontSize: 20
}
}}>
- keyboardHandlingEnabled 如果为false,则导航到新屏幕时,屏幕键盘不会自动关闭。默认为true
- mode 定义渲染和过渡的样式 card:使用标准的iOS和Android屏幕过渡。这是默认值. modal:这有两件事:设置headerMode到screen堆栈,除非指定使屏幕从iOS底部的底部滑入,这是一种常见的iOS模式.
- headerMode 指定标题的呈现方式 float:渲染停留在顶部的单个标题,并在更改屏幕时进行动画处理。iOS上的常见模式。 screen:每个屏幕都有一个附加的标题,标题随屏幕一起淡入和淡出。Android上的常见模式。 none :没有标题。
- Stack.Screen的配置选项 options 可用于配置导航器内的各个屏幕 title 头部标题
function StackScreen() {
return (
// 静态值
<Stack.Navigator>
<Stack.Screen
name="Home"
component={HomeScreen}
options={{ title: 'My home' }}
/>
// 动态获取
<Stack.Screen
name="Profile"
component={HomeScreen}
options={({ route }) => ({ title: route.params.name })}
/>
</Stack.Navigator>
);
}
/* 在组件中修改使用setOptions */
<Button
title="Update the title"
onPress={() => navigation.setOptions({ title: 'Updated!' })}
/>
header 函数,返回一个React Element,显示为标题。如下示例。
header: ({ scene, previous, navigation }) => {
const { options } = scene.descriptor;
const title =
options.headerTitle !== undefined
? options.headerTitle
: options.title !== undefined
? options.title
: scene.route.name;
return (
<MyHeader
title={title}
leftButton={
previous ? <MyBackButton onPress={navigation.goBack} /> : undefined
}
style={options.headerStyle}
/>
);
};
headerShown 是显示还是隐藏屏幕标题。默认情况下显示标题,除非将headerMode其设置为none。设置为 false隐藏标题。在特定屏幕上隐藏标题时,您可能还需要将headerModeprop 设置为screen。 headerTitle 字符串或返回标头要使用的React元素的函数。默认为 title 选项值.
function LogoTitle() {
return (
<Image
style={{ width: 50, height: 50 }}
source={require('@expo/snack-static/react-native-logo.png')}
/>
);
}
function StackScreen() {
return (
<Stack.Navigator>
<Stack.Screen
name="Home"
component={HomeScreen}
options={{ headerTitle: props => <LogoTitle {...props} /> }}
/>
</Stack.Navigator>
);
}
headerTitleAlign 对齐标题。可选择left或center。默认为iOS-center和Android-left headerTitleAllowFontScaling 标头标题字体是否应缩放以符合“文本大小”辅助功能设置。默认为false。 headerBackAllowFontScaling 后退按钮标题字体是否应缩放以符合“文本大小”辅助功能设置。默认为false。 headerBackImage 该函数返回一个React Element以在标题的后退按钮中显示自定义图像。使用函数时,它将tintColor在其参数对象中接收。默认为带有背面图像源的Image组件,它是平台的默认背面图标图像(iOS上为人字形,Android上为箭头)。 headerBackTitle iOS上的后退按钮使用的标题字符串。默认为上一个场景的headerTitle。 headerBackTitleVisible 为后退按钮标题是否可见提供了一个合理的默认值,但是如果您想覆盖它,则可以使用true或false在此选项中使用 headerTruncatedBackTitle 当headerBackTitle屏幕上不适合显示后退按钮时使用的标题字符串。"Back"默认情况下。 headerRight 该函数返回一个React元素以显示在标题的右侧。
function StackScreen() {
return (
<Stack.Navigator>
<Stack.Screen
name="Home"
component={HomeScreen}
options={{
headerTitle: props => <LogoTitle {...props} />,
headerRight: () => (
<Button
onPress={() => alert('This is a button!')}
title="Info"
color="#fff"
/>
),
}}
/>
</Stack.Navigator>
);
}
headerLeft 返回React元素以显示在标题左侧的函数。使用函数时onPress,在呈现时它会接收许多参数(label,labelStyle和more-检查types.tsx以获取完整列表)。 headerStyle 标头的样式对象。例如,您可以在此处指定自定义背景色。 headerTitleStyle 标题组件的样式对象 headerBackTitleStyle 标题的样式对象 headerLeftContainerStyle 自定义headerLeft组件容器的样式,例如添加填充。 headerRightContainerStyle 自定义headerRight组件容器的样式,例如添加填充。 headerTitleContainerStyle 自定义headerTitle组件容器的样式,例如添加填充。默认情况下,headerTitleContainerStyle是具有绝对位置的风格和偏移量都left和right。这可能导致的空白或之间重叠headerLeft和headerTitle如果定制headerLeft被使用。可以通过在中和中进行调整left和right样式来解决。headerTitleContainerStylemarginHorizontalheaderTitleStyle headerTintColor 标头的色调颜色 headerPressColorAndroid 材料波纹的颜色(仅适用于Android> = 5.0) headerTransparent 默认为false。如果为true,则标题将没有背景,除非您明确为其提供背景headerBackground。标头也将浮动在屏幕上,使其与下面的内容重叠。 headerBackground 返回React元素以呈现为标题背景的函数。这对于使用背景(例如图像或渐变)很有用。 例如,可以将其headerTransparent用于渲染模糊视图以创建半透明标题。参考下述示例.
import { BlurView } from 'expo-blur';
<Screen
name="Home"
component={HomeScreen}
options={{
headerTransparent: true,
headerBackground: () => (
<BlurView tint="light" intensity={100} style={StyleSheet.absoluteFill} />
),
}}
/>;
headerStatusBarHeight 在标题顶部添加额外的填充以说明半透明的状态栏。默认情况下,它使用设备安全区域插图中的最大值。传递0或自定义值以禁用默认行为,并自定义高度。 cardShadowEnabled 使用此道具在过渡期间具有可见的阴影。默认为true。 cardOverlayEnabled 使用此道具可以在过渡期间在卡下看到半透明的深色覆盖层。默认为trueAndroid和falseiOS。 cardStyle 堆栈中卡的样式对象。您可以在此处提供自定义背景色,以代替默认背景。您还可以指定{ backgroundColor: ‘transparent’ }使前一个屏幕在下面可见(对于透明模式)。这对于实现模态对话框之类的东西很有用。mode: 'modal’使用透明背景时,还应该在堆栈视图配置中指定,这样以前的屏幕就不会分离并且在下面保持可见。 animationEnabled 屏幕上是否应启用过渡动画。如果将其设置为false,则按下或弹出时屏幕不会动画。默认为true。 animationTypeForReplace 当此屏幕替换另一个屏幕时要使用的动画类型。它采用以下值: push -将使用推送新屏幕的动画 pop -将使用弹出屏幕的动画 默认为push。 当pop被使用时,pop动画被施加到被替换的画面。 gestureEnabled 是否可以使用手势关闭此屏幕。默认为trueiOS,falseAndroid。 gestureResponseDistance 从屏幕边缘开始覆盖触摸距离的对象,以识别手势。该对象可以包含以下属性: horizontal- 数字 -水平方向的距离。默认为25。 vertical- 数字 -垂直方向的距离。默认值为135。 gestureVelocityImpact 决定手势速度相关性的数字。默认值为0.3。 gestureDirection 手势的方向。与动画有关 transitionSpec 屏幕过渡的配置对象。与动画有关.请点击此处查看 cardStyleInterpolator 插卡各部分的插补样式。与动画有关请点击此处查看 headerStyleInterpolator 标头各部分的内插样式。与动画有关请点击此处查看 safeAreaInsets 屏幕的安全区域插图。这用于避免使用诸如缺口和状态栏之类的元素。默认情况下,将自动检测设备的安全区域插图。您可以使用此选项覆盖行为。接受包含以下可选属性的对象: top- 数字 -顶部插图的值,例如包含状态栏和槽口的区域。 right- 数字 -左插图的值。 bottom- 数字 -顶部插图的值,例如底部的区域导航栏。 left。- 数字 -右插图的值。
四、TabNavigator导航
底部导航栏,有的app开发的时候需要用到底部导航栏切换。使用方法跟StackNavigator类似。
1.安装:
npm install @react-navigation/bottom-tabs
2.完整代码
App.js
import 'react-native-gesture-handler';
import React, { Component } from 'react';
import { NavigationContainer } from '@react-navigation/native';
//导入
import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
//引入页面模块
import LoginScreen from './app/views/LoginScreen';
import HomeScreen from './app/views/HomeScreen';
const Tab = createBottomTabNavigator();
function App() {
return (
<NavigationContainer>
<Tab.Navigator
tabBarOptions={{
activeTintColor: 'red',
inactiveTintColor: 'gray',
tabStyle : {
backgroundColor: '#ddd',
paddingBottom: 15,
borderRightWidth: 1,
borderRightColor: '#fff'
},
}}
>
<Tab.Screen name="Home" component={HomeScreen} options={{
headerStyle: {
backgroundColor: '#f4511e',
},
headerTintColor: '#fff',
headerTitleStyle: {
fontWeight: 'bold',
},
}} />
<Tab.Screen name="Login" component={LoginScreen} />
</Tab.Navigator>
</NavigationContainer>
);
}
export default App;
详细参数与配置说明
Tab.Navigator的配置
-
initialRouteName 导航首次加载时要渲染的路线的名称。
-
screenOptions 导航中用于屏幕的默认选项。
-
backBehavior 后退按钮处理的行为。 - initialRoute: 返回初始标签 - order: 返回上一个标签页(按照标签页中显示的顺序) - history: 返回上次访问的标签页 - none:不处理后退按钮
-
lazy 默认为true。如果为false,则所有选项卡都将立即呈现。如果为true,则仅在首次使选项卡处于活动状态时才显示它们。注意:选项卡不会在后续访问时重新呈现。
-
tabBar 返回React元素以显示为选项卡栏的函数
-
tabBarOptions 包含选项卡栏组件的道具的对象。它可以包含以下属性: - activeTintColor -活动标签的标签和图标颜色。 - activeBackgroundColor -活动标签的背景颜色。 - inactiveTintColor -非活动标签的标签和图标颜色。 - inactiveBackgroundColor -非活动标签的背景颜色。 - showLabel -是否显示标签标签,默认为true。 - showIcon -是否显示标签图标,默认为true。 - style -标签栏的样式对象。 - labelStyle -标签标签的样式对象。 - labelPosition-在何处显示与标签图标相关的标签标签。可用值为beside-icon和below-icon。默认为beside-icon。 - tabStyle -标签的样式对象。 - allowFontScaling -标签字体是否应缩放以符合“文本大小”辅助功能设置,默认为true。 - adaptive-标签图标和标签对齐方式是否应根据屏幕尺寸而改变?true对于iOS 11 false,默认值为。如果,标签图标和标签始终垂直对齐。当时true,标签图标和标签在平板电脑上水平对齐。 - safeAreaInset-覆盖forceInset道具。默认为{ bottom: ‘always’, top: ‘never’ }。可用的键top | bottom | left | right随值一起提供’always’ | ‘never’。 - keyboardHidesTabBar-默认为false。如果true在键盘打开时隐藏标签栏。
options 可用于配置导航内的各个屏幕。支持的选项有:
- title 通用标题可以用作备用headerTitle和tabBarLabel。
- tabBarVisible true或false显示或隐藏标签栏(如果未设置),则默认为true。
- tabBarIcon 给定的函数{ focused: boolean, color: string, size: number }返回一个React.Node,以显示在选项卡栏中。
- tabBarLabel 显示在选项卡栏中的选项卡的标题字符串或给定的函数将{ focused: boolean, color: string }返回React.Node,以显示在选项卡栏中。未定义时,使用场景title。
- tabBarButton 该函数返回一个React元素以呈现为选项卡按钮。它包装图标和标签并实现onPress。TouchableWithoutFeedback默认情况下渲染。tabBarButton: props => <TouchableOpacity {…props} />会TouchableOpacity改为使用。
- tabBarAccessibilityLabel 选项卡按钮的辅助功能标签。当用户点击选项卡时,屏幕阅读器会读取该内容。如果您没有标签的标签,建议您进行设置。
- tabBarTestID 在测试中找到此选项卡按钮的ID。
- unmountOnBlur 离开该屏幕时是否应卸载该屏幕。卸载屏幕将重置屏幕中的任何本地状态以及屏幕中嵌套导航器的状态。默认为false。
五、DrawerNavigator导航
1.安装:
npm install @react-navigation/drawer
2.完整代码
App.js
import 'react-native-gesture-handler';
import React, { Component } from 'react';
import { NavigationContainer } from '@react-navigation/native';
//导入
import { createDrawerNavigator } from '@react-navigation/drawer';
//引入页面模块
import LoginScreen from './app/views/LoginScreen';
import HomeScreen from './app/views/HomeScreen';
const Drawer = createDrawerNavigator();
function App() {
return (
<NavigationContainer
drawerStyle={{
backgroundColor: '#c6cbef',
width: 200,
}}
>
<Drawer.Navigator initialRouteName='Home'>
<Drawer.Screen name='Home' component={HomeScreen} />
<Drawer.Screen name='Login' component={LoginScreen} />
</Drawer.Navigator>
</NavigationContainer>
);
}
export default App;
六、组合使用
原生思维是TabNavigator中嵌套StackNavigator,但是这里建议StackNavigator中嵌套TabNavigator。因为可以避免控制TabNavigator的tabbar显示和隐藏问题。