屏幕页面间的导航跳转
移动app很少是由单一的页面组成的。管理多个页面间的呈现和过渡是navigator导航器所必须要处理的一个任务。
这篇文章覆盖了在React Native中的大部分导航组件。如果你对导航也是一知半解,或者说刚入门,你可以尝试使用React Navigation这个npm包。该包提供了一种简单易用的导航方式,可以同时满足对stack navigation和tabbed navigation两种导航模式,并且兼容IOS和Android。而且这都是使用Javascript实现的,方便和状态管理的libraries例如redux做适配。
如果你只是想针对IOS,你当然可以使用NavigatorIOS。这个组件能够提供你想要的原生的样子,而且配置最少。为什么呢,因为这个组件就是基于IOS中的UINavigationController这个类来封装的。所以说啦,这个组件在Android上没法用。
如果你想要在IOS和Android上同时实现一种native的原生效果,或者说你想要把React Native切入到原本就是用原生实现的app中,那么下面的这两个包可以满足你的要求:native-navigation和react-native-navigation.
React Navigation
这个包的是一个独立得library,而且是由社区贡献的,可以实现仅仅通过几行配置代码就能够建立app中的页面跳转。
安装的第一步就是在你的项目中执行以下代码:
npm install --save react-navigation
然后你可以很快的创建一个app,并且设置它的首页和介绍页面:
import {
createStackNavigator,
} from 'react-navigation';
const App = createStackNavigator({
Home: { screen: HomeScreen },
Profile: { screen: ProfileScreen },
});
export default App;
每个页面组件都可以设置很多的导航选项,例如标题名称啊。也可以使用navigation props上的的action creator来链到其他页面。
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的router路由的是非常方便用来复写导航逻辑或者直接整合到Redux中。因为路由router本身就死可以嵌套的,所以说呢开发者完全可以只改写app中的某一块区域的导航逻辑而不做全局的修改。
React Navigation中的视图可以使用原生的组件,并且动画库的话也可以传递60fps的动画到运行native线程的设备上。另一个好处是动画和手势的配置非常容易。
如果想要完全了解React Navigation,可以看下React Navigation的Getting Started Guide,或者看下其他的类似文档,Intro to Navigators。
NavigatorIOS
NavigatorIOS 看上去或是感觉上像是UINavigationController,没错,因为这就是构建在这之上的。
<NavigatorIOS
initialRoute={{
component: MyScene,
title: 'My Initial Scene',
passProps: {myProp: 'foo'},
}}
/>
就像其他的导航系统,NavigatorIOS使用路由来代表页面(screens),不过还是有些许不同。想要渲染哪个组件,通过路由上的组件key值就可以,另外任何想要传递给该组件的参数的话都可以通过passProps来实现。一个“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>
);
}
}
如果想要了解更多关于该组件的内容可以查看NavigatorIOS的参考文档。