RN入门基础12:react-navigation详细讲解
目录
- 一、介绍
- 二、代码及使用
- 1、StackNavigator:普通页面跳转,可传递参数
- 2、TabNavigator:类似底部导航栏
- 3、DrawerNavigator:侧滑菜单导航栏
- 4、属性介绍
一、介绍
RN中文网推荐用react-navigation替代navigator作为新的导航库,从RN 0.43版本开始,官方已经停止维护Navigator了。
首先通过命令安装:
npm install react-navigation --save
// 如果安装了yarn 也可以使用以下命令
yarn add react-navigation
该库包含三类组件:
(1)StackNavigator:普通页面跳转,可传递参数
(2)TabNavigator:类似底部导航栏,用来在同一屏切换不同页面
(3)DrawerNavigator:侧滑菜单导航栏,用于轻松设置带抽屉的屏幕
安装之后导入项目使用即可,如使用StackNavigator:
import {StackNavigator} from 'react-navigation';
二、代码及使用
新建项目: myprojectname
1、StackNavigator:普通页面跳转,可传递参数
1.1、首先要在App.js中定义一个StackNavigator对象,创建基本导航栈
const App = StackNavigator({
// 这个名字任意
HomeScreen: {
screen: HomeScreen
}, // 默认会进入第一个路由视图中,必须要有HomeScreen这个组件
SecondScreen: { screen: SecondScreen }
});
export default App;
1.2、之后创建相关页面
在根目录下,新建mypages文件夹,添加两个JS文件,HomeScreen.js和SecondScreen.js。
HomeScreen.js内容如下:
import React, { Component } from 'react';
import { View, Text, Button } from 'react-native';
export default class HomeScreen extends Component {
static navigationOptions = ({ navigation }) => {
return {
header: () => null, // 隐藏头部
}
}
render() {
const { navigate } = this.props.navigation;
return (
<View>
<Text style={{ fontSize: 32 }}>我是主屏</Text>
</View>
)
}
}
StackNavigator()返回一个组件,所以可以直接通过export导出。目前只有一个空的导航,和中间的文字。
注意:在React Native中,在App.js中export的组件是整个App的入口(或者叫根组件),通常不会直接导出一个'导航栈'组件,而是用另外一个组件渲染'导航栈'组件。修改App.js如下:
//1.创建StackNavigator导航栏
const App = StackNavigator({
// 这个名字任意
HomeScreen: {
screen: HomeScreen
}, // 默认会进入第一个路由视图中,必须要有HomeScreen这个组件
SecondScreen: { screen: SecondScreen }
});
//2.渲染导航栏
export default class myprojectname extends Component {
static navigationOptions = ({ navigation }) => {
return {
header: () => null, // 隐藏头部
}
}
render() {
return (
<App />
)
}
}
1.3、添加第二屏
SecondScreen内容如下:
import React, { Component } from 'react';
import { View, Text } from 'react-native';
import { StackNavigator } from 'react-navigation';
import HomeScreen from './HomeScreen';
export default class SecondScreen extends Component {
static navigationOptions = ({ navigation }) => {
return {
header: () => <Text style={{ fontSize: 32 }}>我是第二屏</Text>
}
}
render() {
return (
<View>
<Text>SecondScreen</Text>
</View>
)
}
}
// 第一个参数,表示导航栈内有哪些视图;
// 第二个是配置参数(可选)
const RootStack = StackNavigator(
{
HomeScreen: {
screen: HomeScreen,
},
SecondScreen: {
screen: SecondScreen,
},
},
{
initialRouteName: 'HomeScreen',
}
);
1.4、双屏切换与数据传递
(1)在主屏(HomeScreen)设置Button,并添加点击,关联到this.props.navigation.navigate('SecondScreen'),这样点击Button会跳转到新界面。修改HomeScreen代码如下:
export default class HomeScreen extends Component {
static navigationOptions = ({ navigation }) => {
return {
header: () => null, // 隐藏头部
}
}
render() {
const { navigate } = this.props.navigation;
return (
<View>
<Text style={{ fontSize: 32 }}>我是主屏</Text>
<Button title="Next" onPress={() => navigate('SecondScreen')} />
</View>
)
}
}
this.props.navigation这个属性会被设置到所有StackNavigator中的页面。navigate('BookDetail')将页面名称传入该方法,可以跳转到指定的StackNavigator页面。如果该名称传入错误,什么也不会发生。
如果在BookDetail页面再添加一个Button跳转到Details页面,页面会一直被添加。
(2)StackNavigator会在非首屏提供一个返回箭头,提供返回操作。也可以通过添加按钮关联goBack返回。此外,StackNavigator自动关联了安卓的返回键,点击设备的返回键也可以返回。
修改SecondScreen如下:
export default class SecondScreen extends Component {
static navigationOptions = ({ navigation }) => {
return {
header: () => <Text style={{ fontSize: 32 }}>我是第二屏</Text>
}
}
render() {
const { navigate } = this.props.navigation;
return (
<View>
<Text>SecondScreen</Text>
<Button title='Next' onPress={() => navigate('SecondScreen')} />
<View style={{ height: 20 }} />
<Button title="Previous" onPress={() => navigate.goBack()} />
</View>
)
}
}
1.5、附加内容(可不看)
在导航器中的每一个页面,都有 navigation 属性,该属性有以下几个属性/方法:
- navigate:跳转到其他页面
- state:当前页面导航器的状态
- setParams:更改路由的参数
- goBack:返回
- dispatch:发送一个action
navigate 调用这个方法可以跳转到导航器中的其他页面,此方法有三个参数:
- routeName:导航器中配置的路由名称
- params:传递参数到下一个页面
- action:action
例如:this.props.navigation.navigate('Find', { param: 'i am the param' });
state 里面包含有传递过来的参数 params、key、路由名称 routeName。
setParams 更改当前页面路由的参数,比如可以用来更新头部的按钮或者标题。
componentDidMount() {
this.props.navigation.setParams({ param: 'i am the new param' })
}
goBack 回退,可以不传,也可以传参数,还可以传 null。
例如:
this.props.navigation.goBack();
this.props.navigation.goBack(null);
this.props.navigation.goBack('Home');
1.6、传递参数
通过在调用navigate方法时传入一个对象:this.props.navigation.navigate('RouteName', { /* params go here */ })
(1)修改HomeScreen中Button,增加参数页数:
render() {
const { navigate } = this.props.navigation;
return (
<View>
<Text style={{ fontSize: 32 }}>我是主屏</Text>
<Button title="Next" onPress={() => navigate('SecondScreen', { page: 0 })} />
</View>
)
}
(2)修改SecondScreen,读取页数,并显示:
render() {
const { navigation } = this.props.navigation;
// 设置变量存放页数
let ID = this.props.navigation.state.params.page + 1;
return (
<View>
<Text>SecondScreen 第{ID}页</Text>
<Button title='Next' onPress={() => this.props.navigation.navigate('SecondScreen', { page: ID })} />
<View style={{ height: 20 }} />
<Button title="Previous" onPress={() => this.props.navigation.goBack()} />
</View>
)
}
1.7、效果如下所示
效果为页面跳转和参数传递,实现了从主屏到第二屏的导航,并可以传递和显示参数。
1.8、最后补充下navigationOptions
通过它配置一些参数,例如title(iOS默认会居中,Android居左)。
(1)如我把标题设置为空:
static navigationOptions = ({ navigation }) => {
return {
header: () => null, // 隐藏头部
}
}
或者设置为具体名字:
static navigationOptions = {
title: 'Home',
};
(2)将this.props放入navigationOptions中使用看起来很方便,但因为这是个静态属性,所以实际上并不会关联到任何实例,自然也不会有props属性。这里需要将navigationOptions变成一个方法,React Navigation会通过一个包含{navigation, navigationOptions, screenProps}的对象调用它。
(3)传递参数设置navigationOptions:
传入导航选项函数的参数是一个具有以下属性的对象:
- navigation:导航栏,包含屏幕的路由在navigation.state。
- screenProps:从上层导航器组件传过来的参数。
- navigationOptions:如果不提供新值,则将使用的默认或先前选项。
static navigationOptions = ({ navigation }) => {
const { params } = navigation.state;
return {
title: params ? params.otherParam : 'A Nested Details Screen',
}
};
(4)在当前屏幕对navigationOptions进行更新:
<Button
title="Update the title"
onPress={() => this.props.navigation.setParams({ otherParam: 'Updated!' })}
/>
(5)调整头部样式:
主要用到三个属性:
- headerStyle:设置包裹头部view的样式,可以设置背景颜色。
- headerTintColor:渲染返回键、标题的颜色。
- headerTitleStyle:设置文字、字体、粗细(fontWeight)。
static navigationOptions = {
title: 'Home',
headerStyle: {
backgroundColor: '#f4511e',
},
headerTintColor: '#fff',
headerTitleStyle: {
fontWeight: 'bold',
},
};
注意:这种设置方式只对当前页面有效。
(6)如果要配置对所有导航页都有效的样式,应该在StackNavigator的第二个参数中配置:
const RootStack = StackNavigator(
{
Home: {
screen: HomeScreen,
},
Details: {
screen: SecondScreen,
},
},
{
initialRouteName: 'Home',
navigationOptions: {
headerStyle: {
backgroundColor: '#f4511e',
},
headerTintColor: '#fff',
headerTitleStyle: {
fontWeight: 'bold',
},
},
}
);
这样所有的样式就一样了,如果某个页面要设置特殊样式,可以单独设置StackNavigator。
也可以通过将公共的navigationOptions通过对象传入进行修改。
(7)自定义一个组件作为标题:
class LogoTitle extends React.Component {
render() {
return (
<Text style={{ flex: 1, fontSize: 30, color: 'green', textAlign: 'center' }}>
标题
</Text>
);
}
}
class HomeScreen extends React.Component {
static navigationOptions = {
headerTitle: <LogoTitle />,
};
}
class BookDetail extends Component {
static navigationOptions = ({ navigation }) => {
return {
header: () => <LogoTitle />,
}
};
}
相关API可以查看 StackNavigator reference。
2、TabNavigator:类似底部导航栏,用来在同一屏切换不同页面
TabNavigator用于创建底部导航栏,允许在同一屏幕上切换不同页面。使用方式类似StackNavigator,但专注于标签导航,适合需要快速切换多个功能模块的应用场景。
3、DrawerNavigator:侧滑菜单导航栏,用于轻松设置带抽屉的屏幕
DrawerNavigator用于创建侧滑菜单导航栏,提供抽屉式导航体验。配置和使用方法与StackNavigator和TabNavigator类似,常用于需要隐藏导航选项或提供更多设置选项的应用。
4、属性介绍
以下是对StackNavigator、TabNavigator和DrawerNavigator的常见属性介绍,帮助开发者更好地配置导航组件。
4.1、StackNavigator属性介绍
- navigationOptions:配置StackNavigator的一些属性。
- title:标题,如果设置了这个导航栏和标签栏的title就会变成一样的,不推荐使用。
- header:可以设置一些导航的属性,如果隐藏顶部导航栏只要将这个属性设置为null。
- headerTitle:设置导航栏标题,推荐。
- headerBackTitle:设置跳转页面左侧返回箭头后面的文字,默认是上一个页面的标题。可以自定义,也可以设置为null。
- headerTruncatedBackTitle:设置当上个页面标题不符合返回箭头后的文字时,默认改成"返回"。
- headerRight:设置导航条右侧。可以是按钮或者其他视图控件。
- headerLeft:设置导航条左侧。可以是按钮或者其他视图控件。
- headerStyle:设置导航条的样式。背景色,宽高等。
- headerTitleStyle:设置导航栏文字样式。
- headerBackTitleStyle:设置导航栏‘返回’文字样式。
- headerTintColor:设置导航栏颜色。
- headerPressColorAndroid:安卓独有的设置颜色纹理,需要安卓版本大于5.0。
- gesturesEnabled:是否支持滑动返回手势,iOS默认支持,安卓默认关闭。
- screen:对应界面名称,需要填入import之后的页面。
- mode:定义跳转风格,card:使用iOS和安卓默认的风格;modal:iOS独有的使屏幕从底部画出,类似iOS的present效果。
- headerMode:返回上级页面时动画效果,float:iOS默认的效果;screen:滑动过程中,整个页面都会返回;none:无动画。
- cardStyle:自定义设置跳转效果。
- transitionConfig:自定义设置滑动返回的配置。
- onTransitionStart:当转换动画即将开始时被调用的功能。
- onTransitionEnd:当转换动画完成,将被调用的功能。
- path:路由中设置的路径的覆盖映射配置。
- initialRouteName:设置默认的页面组件,必须是上面已注册的页面组件。
- initialRouteParams:初始路由参数。
4.2、TabNavigator属性介绍
- screen:和导航的功能是一样的,对应界面名称,可以在其他页面通过这个screen传值和跳转。
- navigationOptions:配置TabNavigator的一些属性。
- title:标题,会同时设置导航条和标签栏的title。
- tabBarVisible:是否隐藏标签栏。默认不隐藏(true)。
- tabBarIcon:设置标签栏的图标。需要给每个都设置。
- tabBarLabel:设置标签栏的title。推荐。
导航栏配置:
- tabBarPosition:设置tabbar的位置,iOS默认在底部,安卓默认在顶部。(属性值:'top','bottom')
- swipeEnabled:是否允许在标签之间进行滑动。
- animationEnabled:是否在更改标签时显示动画。
- lazy:是否根据需要懒惰呈现标签,而不是提前,意思是在app打开的时候将底部标签栏全部加载,默认false,推荐为true。
- initialRouteName:设置默认的页面组件。
- backBehavior:按 back 键是否跳转到第一个Tab(首页),none 为不跳转。
- tabBarOptions:配置标签栏的一些属性。
iOS属性:
- activeTintColor:label和icon的前景色 活跃状态下。
- activeBackgroundColor:label和icon的背景色 活跃状态下。
- inactiveTintColor:label和icon的前景色 不活跃状态下。
- inactiveBackgroundColor:label和icon的背景色 不活跃状态下。
- showLabel:是否显示label,默认开启。
- style:tabbar的样式。
- labelStyle:label的样式。
安卓属性:
- activeTintColor:label和icon的前景色 活跃状态下。
- inactiveTintColor:label和icon的前景色 不活跃状态下。
- showIcon:是否显示图标,默认关闭。
- showLabel:是否显示label,默认开启。
- style:tabbar的样式。
- labelStyle:label的样式。
- upperCaseLabel:是否使标签大写,默认为true。
- pressColor:material涟漪效果的颜色(安卓版本需要大于5.0)。
- pressOpacity:按压标签的透明度变化(安卓版本需要小于5.0)。
- scrollEnabled:是否启用可滚动选项卡。
- tabStyle:tab的样式。
- indicatorStyle:标签指示器的样式对象(选项卡底部的行)。安卓底部会多出一条线,可以将height设置为0来暂时解决这个问题。
- labelStyle:label的样式。
- iconStyle:图标样式。
4.3、DrawerNavigator属性介绍
DrawerNavigatorConfig:
- drawerWidth:抽屉的宽度。
- drawerPosition:选项是左或右。默认为左侧位置。
- contentComponent:用于呈现抽屉内容的组件,例如导航项。接收抽屉的导航。默认为DrawerItems。
- contentOptions:配置抽屉内容。
- initialRouteName:初始路由的routeName。
- order:定义抽屉项目顺序的routeNames数组。
- 路径:提供routeName到路径配置的映射,它覆盖routeConfigs中设置的路径。
- backBehavior:后退按钮是否会切换到初始路由?如果是,设置为initialRoute,否则为none。默认为initialRoute行为。
DrawerItems的contentOptions属性:
- activeTintColor:活动标签的标签和图标颜色。
- activeBackgroundColor:活动标签的背景颜色。
- inactiveTintColor:非活动标签的标签和图标颜色。
- inactiveBackgroundColor:非活动标签的背景颜色。
- 内容部分的样式样式对象。
- labelStyle:当您的标签是字符串时,要覆盖内容部分中的文本样式的样式对象。