导航 Navigator
在一个实际的移动应用当中,极少会有只包含一个界面的应用,大部分情况下,需要在应用的各个界面之间进行跳转。因此,我们需要使用导航组件来引导和管理界面之间的跳转。
在大多数 iOS 和 Android 应用中,我们经常会看到在顶部或者底部有「返回」或者跳转到其他界面的按钮,这些都属于导航组件,导航组件还有一个作用就是管理界面与界面之间的跳转。
场景 Scene
要了解导航组件,就必须引入「场景(Scene)」的概念。简单说,导航组件管理的每一个用户界面都被称作一个场景,导航组件所做的就是负责管理用户界面从一个场景跳转到另一个场景。一个场景其实就是一个普通的组件,有自己的属性(props)、状态(state)以及子组件,当它被一个导航组件管理并作为其中的一个用户界面时,便被成为一个场景。
我们用一个例子来解释。首先创建一个 MyScene.js
文件,在其中创建一个视图组件 MyScene
:
import React, { Component, PropTypes } from 'react'
import { View, Text} from 'react-native'
export default class MyScene extends Component {
static get defaultProps() {
return {
title: 'MyScene'
}
}
render() {
return(
<View style={{paddingTop: 22}}>
<Text>This is: {this.props.title}</Text>
</View>
)
}
}
然后,在 index.*.js
中引入该组件:
import MyScene from './MyScene';
之后,像使用其他视图组件一样使用便可以了,此时运行,屏幕上会显示一行文本:“This is MyScene”。
使用 Navigator
接下来,我们开始使用 Navigator 用 MyScene 组件创建多个可以相互跳转的界面。
先来编写 index.*.js
的代码:
/**
* Sample React Native App
* https://github.com/facebook/react-native
* @flow
*/
import React, { Component } from 'react';
import {
AppRegistry,
View,
Navigator,
Text
} from 'react-native';
import MyScene from './MyScene';
export default class HelloWorld extends Component {
render() {
return (
<Navigator
initialRoute = {{ title: 'My Initial Scene', index: 0 }}
renderScene = {(route, navigator) =>
<MyScene
title = {route.title}
// Function to call when a new scene should be diplayed
onForward = {() => {
const nextIndex = route.index + 1;
navigator.push({
title: 'Scene' + nextIndex,
index: nextIndex,
});
}}
// Function to call to go back to the previous Scene
onBack = {() => {
if (route.index > 0) {
navigator.pop();
}
}}
/>
}
/>
)
}
}
AppRegistry.registerComponent('HelloWorld', () => HelloWorld);
在根视图中,以 Navigator
为最外层的组件,该组件有两个属性:
-
initialRoute
:该属性用来描述导航组件要展示的第一个场景。 -
renderScene
:该属性用来渲染视图,两个参数分别是当前场景的描述,以及当前的导航视图。
在上面的例子中,我们给 MyScene
传入了三个属性值,这三个属性会在之后重写 MyScene
组件时实现它们的功能。
-
title
:场景的标题。 -
onForward
:进入下个场景的操作。 -
onBack
:返回上个场景的操作。
在 Navigator 组件中,通过 navigator.push()
方法来进行新场景的推入,使用 navigator.pop()
方法来弹出当前场景,返回上一个场景。因此,将这些操作放入组件的属性中,一遍在创建组件时,将这些操作绑定到相应的按钮上。
我们还需要重写 MyScene
组件:
import React, { Component, PropTypes } from 'react'
import { View, Text, Navigator, TouchableHighlight } from 'react-native'
export default class MyScene extends Component {
static get defaultProps() {
return {
title: 'MyScene'
}
}
render() {
return(
<View style={{paddingTop: 22}}>
<Text>Current Scene: {this.props.title}</Text>
<TouchableHighlight onPress = {this.props.onForward}>
<Text>Tap me to load the next scene</Text>
</TouchableHighlight>
<TouchableHighlight onPress = {this.props.onBack}>
<Text>Tap me to go back</Text>
</TouchableHighlight>
</View>
)
}
}
MyScene.propTypes = {
title: PropTypes.string.isRequired,
onForward: PropTypes.func.isRequired,
onBack: PropTypes.func.isRequired
};
上例中引入了 TouchableHighlight
组件用来处理点击事件来执行场景跳转的函数。
此时运行应用,效果如下: