🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
> [Navigator](http://facebook.github.io/react-native/docs/navigator.html#content) ## 属性 | 名称 | 类型 | 意义 | 默认值 | | --- | --- | --- | --- | | configureScene | function | 配置Scene切换的动画效果 | 无 | | initialRoute | object | 设置场景的开始route | 无 | | initialRouteStack | object | route栈,如果没有initialRoute,该initialRouteStack对象就是必须要设置的,但是好玩的是,该对象的默认值就是只包含initialRoute的数组 | 只包含initialRoute的数组 | | navigationBar | node | 导航条控件节点 | 无 | | navigator | object | 指代Navigator控件 | 无 | | onDidFocus | function | 当每个scene的新route过渡完成时调用(navigationContext.addListener(‘didfocus’, callback)用法已经废弃) | 无 | | onWillFocus | function | 每一个导航栏过渡开始前调用(navigationContext.addListener(‘willfocus’, callback) 用法已废弃) | 无 | | renderScene | function | 为当前route设置的scene | 无 | | sceneStyle | Style | 为每一个scene容器设置样式 | 无 | ## 实例 ## index.io.js ~~~ 'use strict'; var React = require('react-native'); var UIExplorerList = require('./UIExplorerList.ios'); var NavigatorExample = require('./Navigator/NavigatorExample'); var { AppRegistry, NavigatorIOS, StyleSheet, } = React; var UIExplorerApp = React.createClass({ getInitialState: function() { return { openExternalExample: (null: ?React.Component), }; }, render: function() { return ( <NavigatorExample/> ); } }); var styles = StyleSheet.create({ container: { flex: 1, }, itemWrapper: { backgroundColor: '#eaeaea', }, }); AppRegistry.registerComponent('hellowrold', () => UIExplorerApp); ~~~ ## Navigator/NavigatorExample.js ~~~ /** * The examples provided by Facebook are for non-commercial testing and * evaluation purposes only. * * Facebook reserves all rights not expressly granted. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL * FACEBOOK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ 'use strict'; var React = require('react-native'); var { Navigator, PixelRatio, ScrollView, StyleSheet, Text, TouchableHighlight, } = React; var BreadcrumbNavSample = require('./BreadcrumbNavSample'); var NavigationBarSample = require('./NavigationBarSample'); var JumpingNavSample = require('./JumpingNavSample'); class NavButton extends React.Component { render() { return ( <TouchableHighlight style={styles.button} underlayColor="#B5B5B5" onPress={this.props.onPress}> <Text style={styles.buttonText}>{this.props.text}</Text> </TouchableHighlight> ); } } class NavMenu extends React.Component { render() { return ( <ScrollView style={styles.scene}> <Text style={styles.messageText}>{this.props.message}</Text> <NavButton onPress={() => { this.props.navigator.push({ message: 'Swipe right to dismiss', sceneConfig: Navigator.SceneConfigs.FloatFromRight, }); }} text="Float in from right" /> <NavButton onPress={() => { this.props.navigator.push({ message: 'Swipe down to dismiss', sceneConfig: Navigator.SceneConfigs.FloatFromBottom, }); }} text="Float in from bottom" /> <NavButton onPress={() => { this.props.navigator.pop(); }} text="Pop" /> <NavButton onPress={() => { this.props.navigator.popToTop(); }} text="Pop to top" /> <NavButton onPress={() => { this.props.navigator.push({ id: 'navbar' }); }} text="Navbar Example" /> <NavButton onPress={() => { this.props.navigator.push({ id: 'jumping' }); }} text="Jumping Example" /> <NavButton onPress={() => { this.props.navigator.push({ id: 'breadcrumbs' }); }} text="Breadcrumbs Example" /> <NavButton onPress={() => { this.props.onExampleExit(); }} text="Exit <Navigator> Example" /> </ScrollView> ); } } var TabBarExample = React.createClass({ statics: { title: '<Navigator>', description: 'JS-implemented navigation', }, renderScene: function(route, nav) { switch (route.id) { case 'navbar': return <NavigationBarSample navigator={nav} />; case 'breadcrumbs': return <BreadcrumbNavSample navigator={nav} />; case 'jumping': return <JumpingNavSample navigator={nav} />; default: return ( <NavMenu message={route.message} navigator={nav} onExampleExit={this.props.onExampleExit} /> ); } }, render: function() { return ( <Navigator ref={this._setNavigatorRef} style={styles.container} initialRoute={{ message: "First Scene", }} renderScene={this.renderScene} configureScene={(route) => { if (route.sceneConfig) { return route.sceneConfig; } return Navigator.SceneConfigs.FloatFromBottom; }} /> ); }, componentWillUnmount: function() { this._listeners && this._listeners.forEach(listener => listener.remove()); }, _setNavigatorRef: function(navigator) { if (navigator !== this._navigator) { this._navigator = navigator; if (navigator) { var callback = (event) => { console.log( `TabBarExample: event ${event.type}`, { route: JSON.stringify(event.data.route), target: event.target, type: event.type, } ); }; // Observe focus change events from the owner. this._listeners = [ navigator.navigationContext.addListener('willfocus', callback), navigator.navigationContext.addListener('didfocus', callback), ]; } } }, }); var styles = StyleSheet.create({ messageText: { fontSize: 17, fontWeight: '500', padding: 15, marginTop: 50, marginLeft: 15, }, container: { flex: 1, }, button: { backgroundColor: 'white', padding: 15, borderBottomWidth: 1 / PixelRatio.get(), borderBottomColor: '#CDCDCD', }, buttonText: { fontSize: 17, fontWeight: '500', }, scene: { flex: 1, paddingTop: 20, backgroundColor: '#EAEAEA', } }); TabBarExample.external = true; module.exports = TabBarExample; ~~~ ## Navigator/NavigationBarSample.js ~~~ /** * The examples provided by Facebook are for non-commercial testing and * evaluation purposes only. * * Facebook reserves all rights not expressly granted. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL * FACEBOOK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ 'use strict'; var React = require('react-native'); var { PixelRatio, Navigator, ScrollView, StyleSheet, Text, TouchableHighlight, TouchableOpacity, View, } = React; var cssVar = require('cssVar'); class NavButton extends React.Component { render() { return ( <TouchableHighlight style={styles.button} underlayColor="#B5B5B5" onPress={this.props.onPress}> <Text style={styles.buttonText}>{this.props.text}</Text> </TouchableHighlight> ); } } var NavigationBarRouteMapper = { LeftButton: function(route, navigator, index, navState) { if (index === 0) { return null; } var previousRoute = navState.routeStack[index - 1]; return ( <TouchableOpacity onPress={() => navigator.pop()} style={styles.navBarLeftButton}> <Text style={[styles.navBarText, styles.navBarButtonText]}> {previousRoute.title} </Text> </TouchableOpacity> ); }, RightButton: function(route, navigator, index, navState) { return ( <TouchableOpacity onPress={() => navigator.push(newRandomRoute())} style={styles.navBarRightButton}> <Text style={[styles.navBarText, styles.navBarButtonText]}> Next </Text> </TouchableOpacity> ); }, Title: function(route, navigator, index, navState) { return ( <Text style={[styles.navBarText, styles.navBarTitleText]}> {route.title} [{index}] </Text> ); }, }; function newRandomRoute() { return { title: '#' + Math.ceil(Math.random() * 1000), }; } var NavigationBarSample = React.createClass({ componentWillMount: function() { var navigator = this.props.navigator; var callback = (event) => { console.log( `NavigationBarSample : event ${event.type}`, { route: JSON.stringify(event.data.route), target: event.target, type: event.type, } ); }; // Observe focus change events from this component. this._listeners = [ navigator.navigationContext.addListener('willfocus', callback), navigator.navigationContext.addListener('didfocus', callback), ]; }, componentWillUnmount: function() { this._listeners && this._listeners.forEach(listener => listener.remove()); }, render: function() { return ( <Navigator debugOverlay={false} style={styles.appContainer} initialRoute={newRandomRoute()} renderScene={(route, navigator) => ( <ScrollView style={styles.scene}> <Text style={styles.messageText}>{route.content}</Text> <NavButton onPress={() => { navigator.immediatelyResetRouteStack([ newRandomRoute(), newRandomRoute(), newRandomRoute(), ]); }} text="Reset w/ 3 scenes" /> <NavButton onPress={() => { this.props.navigator.pop(); }} text="Exit NavigationBar Example" /> </ScrollView> )} navigationBar={ <Navigator.NavigationBar routeMapper={NavigationBarRouteMapper} style={styles.navBar} /> } /> ); }, }); var styles = StyleSheet.create({ messageText: { fontSize: 17, fontWeight: '500', padding: 15, marginTop: 50, marginLeft: 15, }, button: { backgroundColor: 'white', padding: 15, borderBottomWidth: 1 / PixelRatio.get(), borderBottomColor: '#CDCDCD', }, buttonText: { fontSize: 17, fontWeight: '500', }, navBar: { backgroundColor: 'white', }, navBarText: { fontSize: 16, marginVertical: 10, }, navBarTitleText: { color: cssVar('fbui-bluegray-60'), fontWeight: '500', marginVertical: 9, }, navBarLeftButton: { paddingLeft: 10, }, navBarRightButton: { paddingRight: 10, }, navBarButtonText: { color: cssVar('fbui-accent-blue'), }, scene: { flex: 1, paddingTop: 20, backgroundColor: '#EAEAEA', }, }); module.exports = NavigationBarSample; ~~~ ## Navigator/BreadcrumbNavSample.js ~~~ /** * The examples provided by Facebook are for non-commercial testing and * evaluation purposes only. * * Facebook reserves all rights not expressly granted. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL * FACEBOOK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ 'use strict'; var React = require('react-native'); var { PixelRatio, Navigator, StyleSheet, ScrollView, Text, TouchableHighlight, TouchableOpacity, View, } = React; var _getRandomRoute = function() { return { title: '#' + Math.ceil(Math.random() * 1000), }; }; class NavButton extends React.Component { render() { return ( <TouchableHighlight style={styles.button} underlayColor="#B5B5B5" onPress={this.props.onPress}> <Text style={styles.buttonText}>{this.props.text}</Text> </TouchableHighlight> ); } } var BreadcrumbNavSample = React.createClass({ componentWillMount: function() { this._navBarRouteMapper = { rightContentForRoute: function(route, navigator) { return null; }, titleContentForRoute: function(route, navigator) { return ( <TouchableOpacity onPress={() => navigator.push(_getRandomRoute())}> <Text style={styles.titleText}>{route.title}</Text> </TouchableOpacity> ); }, iconForRoute: function(route, navigator) { return ( <TouchableOpacity onPress={() => { navigator.popToRoute(route); }} style={styles.crumbIconPlaceholder} /> ); }, separatorForRoute: function(route, navigator) { return ( <TouchableOpacity onPress={navigator.pop} style={styles.crumbSeparatorPlaceholder} /> ); } }; }, _renderScene: function(route, navigator) { return ( <ScrollView style={styles.scene}> <NavButton onPress={() => { navigator.push(_getRandomRoute()) }} text="Push" /> <NavButton onPress={() => { navigator.immediatelyResetRouteStack([_getRandomRoute(), _getRandomRoute()]) }} text="Reset w/ 2 scenes" /> <NavButton onPress={() => { navigator.popToTop() }} text="Pop to top" /> <NavButton onPress={() => { navigator.replace(_getRandomRoute()) }} text="Replace" /> <NavButton onPress={() => { this.props.navigator.pop(); }} text="Close breadcrumb example" /> </ScrollView> ); }, render: function() { return ( <Navigator style={styles.container} initialRoute={_getRandomRoute()} renderScene={this._renderScene} navigationBar={ <Navigator.BreadcrumbNavigationBar routeMapper={this._navBarRouteMapper} /> } /> ); }, }); var styles = StyleSheet.create({ scene: { paddingTop: 50, flex: 1, }, button: { backgroundColor: 'white', padding: 15, borderBottomWidth: 1 / PixelRatio.get(), borderBottomColor: '#CDCDCD', }, buttonText: { fontSize: 17, fontWeight: '500', }, container: { overflow: 'hidden', backgroundColor: '#dddddd', flex: 1, }, titleText: { fontSize: 18, color: '#666666', textAlign: 'center', fontWeight: 'bold', lineHeight: 32, }, crumbIconPlaceholder: { flex: 1, backgroundColor: '#666666', }, crumbSeparatorPlaceholder: { flex: 1, backgroundColor: '#aaaaaa', }, }); module.exports = BreadcrumbNavSample; ~~~ ## Navigator/JumpingNavSample.js ~~~ /** * The examples provided by Facebook are for non-commercial testing and * evaluation purposes only. * * Facebook reserves all rights not expressly granted. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL * FACEBOOK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ 'use strict'; var React = require('react-native'); var { Navigator, PixelRatio, StyleSheet, ScrollView, TabBarIOS, Text, TouchableHighlight, View, } = React; var _getRandomRoute = function() { return { randNumber: Math.ceil(Math.random() * 1000), }; }; class NavButton extends React.Component { render() { return ( <TouchableHighlight style={styles.button} underlayColor="#B5B5B5" onPress={this.props.onPress}> <Text style={styles.buttonText}>{this.props.text}</Text> </TouchableHighlight> ); } } var ROUTE_STACK = [ _getRandomRoute(), _getRandomRoute(), _getRandomRoute(), ]; var INIT_ROUTE_INDEX = 1; class JumpingNavBar extends React.Component { constructor(props) { super(props); this.state = { tabIndex: props.initTabIndex, }; } handleWillFocus(route) { var tabIndex = ROUTE_STACK.indexOf(route); this.setState({ tabIndex, }); } render() { return ( <View style={styles.tabs}> <TabBarIOS> <TabBarIOS.Item icon={require('image!tabnav_notification')} selected={this.state.tabIndex === 0} onPress={() => { this.props.onTabIndex(0); this.setState({ tabIndex: 0, }); }}> <View /> </TabBarIOS.Item> <TabBarIOS.Item icon={require('image!tabnav_list')} selected={this.state.tabIndex === 1} onPress={() => { this.props.onTabIndex(1); this.setState({ tabIndex: 1, }); }}> <View /> </TabBarIOS.Item> <TabBarIOS.Item icon={require('image!tabnav_settings')} selected={this.state.tabIndex === 2} onPress={() => { this.props.onTabIndex(2); this.setState({ tabIndex: 2, }); }}> <View /> </TabBarIOS.Item> </TabBarIOS> </View> ); } } var JumpingNavSample = React.createClass({ render: function() { return ( <Navigator debugOverlay={false} style={styles.appContainer} ref={(navigator) => { this._navigator = navigator; }} initialRoute={ROUTE_STACK[INIT_ROUTE_INDEX]} initialRouteStack={ROUTE_STACK} renderScene={this.renderScene} configureScene={() => ({ ...Navigator.SceneConfigs.HorizontalSwipeJump, })} navigationBar={ <JumpingNavBar ref={(navBar) => { this.navBar = navBar; }} initTabIndex={INIT_ROUTE_INDEX} routeStack={ROUTE_STACK} onTabIndex={(index) => { this._navigator.jumpTo(ROUTE_STACK[index]); }} /> } /> ); }, renderScene: function(route, navigator) { var backBtn; var forwardBtn; if (ROUTE_STACK.indexOf(route) !== 0) { backBtn = ( <NavButton onPress={() => { navigator.jumpBack(); }} text="jumpBack" /> ); } if (ROUTE_STACK.indexOf(route) !== ROUTE_STACK.length - 1) { forwardBtn = ( <NavButton onPress={() => { navigator.jumpForward(); }} text="jumpForward" /> ); } return ( <ScrollView style={styles.scene}> <Text style={styles.messageText}>#{route.randNumber}</Text> {backBtn} {forwardBtn} <NavButton onPress={() => { navigator.jumpTo(ROUTE_STACK[1]); }} text="jumpTo middle route" /> <NavButton onPress={() => { this.props.navigator.pop(); }} text="Exit Navigation Example" /> <NavButton onPress={() => { this.props.navigator.push({ message: 'Came from jumping example', }); }} text="Nav Menu" /> </ScrollView> ); }, }); var styles = StyleSheet.create({ button: { backgroundColor: 'white', padding: 15, borderBottomWidth: 1 / PixelRatio.get(), borderBottomColor: '#CDCDCD', }, buttonText: { fontSize: 17, fontWeight: '500', }, appContainer: { overflow: 'hidden', backgroundColor: '#dddddd', flex: 1, }, messageText: { fontSize: 17, fontWeight: '500', padding: 15, marginTop: 50, marginLeft: 15, }, scene: { flex: 1, paddingTop: 20, backgroundColor: '#EAEAEA', }, tabs: { height: 50, } }); module.exports = JumpingNavSample; ~~~ ## 效果 ![](https://box.kancloud.cn/2016-01-07_568e13f25b2a4.jpg)