导航器跳转页面
移动端应用程序通常不会只有一个屏幕(页面),管理多个屏幕(页面)的呈现和跳转通常由称为导航器的处理来处理。
本文档涵盖了 React-Native 之中各种常见的导航组件。如果您刚刚接触导航组件,不如选择React Navigation进行学习。React Navigation 提供了一个易于使用的导航解决方案,能够在 iOS 和 Android 上呈现常见堆栈导航和选项卡式导航。 由于其是由 JavaScript 实现的,它在与诸如redux等状态管理库进行集成时有着很好的可配置性和灵活性。
如果您只针对 iOS 进行开发,那么您可以使用NavigatorIOS导航组件,因为它提供了 ios 原生UINavigationController
类的包装(译者注:与 iOS 系统原生外观一致)。但是,该组件无法在 Android 上运行。
如果您希望在 iOS 和 Android 上实现原生的外观和体验,或者将 React-Native 集成到原生开发的应用中,以下的两个库都能支持这种需求:native-navigation, react-native-navigation。
React Navigation
社区今后主推的方案是一个单独的导航库react-navigation
,它的使用十分简单。
首先在你的应用程序中安装此组件:
npm install --save react-navigation
接下来你就可以快速创建一个有两个页面(Home 和 Profile)的应用了:
import {
StackNavigator,
} from 'react-navigation';
const App = StackNavigator({
Home: { screen: HomeScreen },
Profile: { screen: ProfileScreen },
});
每一个screen
组件都可以单独设置导航选项,例如导航头的标题。还可以使用navigation
属性中的方法去跳转到别的页面:
class HomeScreen extends React.Component {
static navigationOptions = {
title: 'Welcome',
};
render() {
const { navigate } = this.props.navigation;
return (
<Button
title="Go to Jane's profile"
onPress={() =>
navigate('Profile', { name: 'Jane' })
}
/>
);
}
}
React Navigation
的路由写法使其非常容易扩展导航逻辑,或是整合到redux
中。由于路由可以嵌套使用,因而开发者可以根据不同页面编写不同的导航逻辑,且彼此互不影响。
React Navigation
中的视图是原生组件,同时用到了运行在原生线程上的 Animated
动画库,因而性能表现十分流畅。此外其动画形式和手势都非常便于定制。
有关React Navigation
的完整介绍,请按照React Navigation Getting Started Guide或浏览其他文档,例如Navigator
的Intro to Navigators。
NavigatorIOS
NavigatorIOS
的外观和体验与UINavigationController
非常相似,因为NavigatorIOS
实际上是建立在它之上的。
<NavigatorIOS
initialRoute={{
component: MyScene,
title: 'My Initial Scene',
passProps: {myProp: 'foo'},
}}
/>
与其他导航组件一样,NavigatorIOS
也使用路由对象来描述场景,但有一些重要的区别。 其中要渲染的组件在路由对象的 component 字段中指定,要给目标组件传递的参数则写在 passProps 中。被渲染的 component 都会自动接受到一个名为 navigator 的属性,你可以直接调用此对象(this.props.navigator)的push
和 pop
方法。
由于 NavigatorIOS
使用的是原生的 UIKit 导航,所以它会自动渲染一个带有返回按钮和标题的导航栏。
import React from 'react';
import PropTypes from 'prop-types';
import {Button, NavigatorIOS, Text, View} from 'react-native';
export default class NavigatorIOSApp extends React.Component {
render() {
return (
<NavigatorIOS
initialRoute={{
component: MyScene,
title: 'My Initial Scene',
passProps: {index: 1},
}}
style={{flex: 1}}
/>
);
}
}
class MyScene extends React.Component {
static propTypes = {
route: PropTypes.shape({
title: PropTypes.string.isRequired,
}),
navigator: PropTypes.object.isRequired,
};
constructor(props, context) {
super(props, context);
this._onForward = this._onForward.bind(this);
}
_onForward() {
let nextIndex = ++this.props.index;
this.props.navigator.push({
component: MyScene,
title: 'Scene ' + nextIndex,
passProps: {index: nextIndex},
});
}
render() {
return (
<View>
<Text>Current Scene: {this.props.title}</Text>
<Button
onPress={this._onForward}
title="Tap me to load the next scene"
/>
</View>
);
}
}