跨平台开发RN-组件Navigator
Navigator组件
- 作用:处理应用程序中不同场景之间的转换。
- 特点:
- 是跨平台的导航组件,不管在 iOS 还是 Android 系统下都能使用。
- 注意:默认没有包含导航栏,我们可以实现一个自定义导航栏,也可以使用 NavigatorBar 组件来实现
- Navigator安装
- 从0.44版本开始,Navigator被从react native的核心组件库中剥离到了一个名为
react-native-deprecated-custom-components
的单独模块中 - 导入
navigator
-
打开终端,cd 到你的文件目录
// 导入navigator npm install react-native-deprecated-custom-components --save
-
- 从0.44版本开始,Navigator被从react native的核心组件库中剥离到了一个名为
- 两个核心要素
- navigator: 一个用来管理所有界面对象的栈,人称之为“路由栈”,也叫导航
- route: 路由栈里的每一个对象,称之为“路由”,用来存储每一个页面组件以及一些需要传递给对应界面的props参数
常用的属性
initialRoute ={* name: name, component: component }}
- 这个指定了默认的页面,也就是启动的组件页面
- 初始路由,也就是我们需要在navigator栈底放置的路由,因此此时也是栈顶,因此也就是初始化整个APP的首页
configureScene
设置页面跳转样式-
configureScene
函数应该返回一个场景配置对象用来定义页面切换的动画。可用场景配置选项为:PushFromRight(默认) FloatFromRight FloatFromLeft FloatFromBottom FloatFromBottomAndroid FadeAndroid SwipeFromLeft HorizontalSwipeJump HorizontalSwipeJumpFromRight HorizontalSwipeJumpFromLeft VerticalUpSwipeJump VerticalDownSwipeJump
-
使用:
configureScene ={() => { return Navigator. SceneConfigs .HorizontalSwipeJump; }}
-
renderScene
-
具体是方法如下:
renderScene={(route,navigator)=>{ let Component = route.component; return <Component {...route.passProps} navigator={navigator}/>; }} />
- 渲染当前路由场景,就是说渲染出路由栈中栈顶(将要显示)的那个组件,回调方法中的参数:
- route: 当前路由
- navigator: 路由栈
...route
: 是一个ES6的语法,表示将路由route中所有的键值对以属性赋值的方式展开,也就是{name:'poper',gender:'man'}
到name='poper',gender='man'
转化,这样就把route对象中所有的键值对,就很容易的放到route.component组件的props属性中去;因此,这个语法在自定义控件的时候也经常用到,主要用来兼容组件中其他所有属性,如自定义ListView兼容官方LsitView所有属性。- 两个参数中的route包含的是initial的时候传递的name和component,而navigator是一个我们需要用的Navigator的对象;
- 所以当我们拿到route中的component的时候,我们就可以将navigator传递给它,正因为如此,我们的组件
HomeScene
才可以通过this.props.navigator
,拿到路由。
-
initialRouteStack [object]
参数对象数组- 这是一个初始化的路由数组进行初始化。如果
initalRoute
属性没有设置的话,那么就必须设置initialRouteStack
属性,使用该最后一项作为初始路由。 如果initalRouteStack
属性没有设置的话,该会生成只包含initalRoute
值的数组
- 这是一个初始化的路由数组进行初始化。如果
navigationBar node
- 该为可选的参数,在页面切换中用来提供一个导航栏
navigator object
- 该为可选参数,可以从父类导航器中获取导航器对象
sceneStyle 样式风格
- 该继承了View视图的所有样式风格,用于设置每个页面容器的风格
onWillFocus:
- 每个navigator组件转换之前,会回调onWillFocus函数。
onDidFocus:
- 每个navigator组件转换之后,会回调onDidFocus函数。
常用的导航器方法
- 当获取了导航器对象的引用,我们可以进行调用以下一些方法来实现页面导航功能:
- 如下:
getCurrentRoutes()
- 该进行返回存在的路由列表信息
jumpBack()
- 该进行回退操作 但是该不会卸载(删除)当前的页面
jumpForward()
- 进行跳转到相当于当前页面的下一个页面
jumpTo(route)
- 根据传入的一个路由信息,跳转到一个指定的页面(该页面不会卸载删除)
push(route)
- 导航切换到一个新的页面中,新的页面进行压入栈。通过jumpForward()方法可以回退过去
pop()
- 当前页面弹出来,跳转到栈中下一个页面,并且卸载删除掉当前的页面
replace(route)
- 只用传入的路由的指定页面进行替换掉当前的页面
replaceAtIndex(route,index)
- 传入路由以及位置索引,使用该路由指定的页面跳转到指定位置的页面
replacePrevious(route)
- 传入路由,通过指定路由的页面替换掉前一个页面
resetTo(route)
- 进行导航到新的界面,并且重置整个路由栈
immediatelyResetRouteStack(routeStack)
- 该通过一个路由页面数组来进行重置路由栈
popToRoute(route)
- 进行弹出相关页面,跳转到指定路由的页面,弹出来的页面会被卸载删除
popToTop()
- 进行弹出页面,导航到栈中的第一个页面,弹出来的所有页面会被卸载删除
默认写法
<Navigator
initialRoute = {* name: defaultName, component: defaultComponent }}
configureScene={()=>{
return Navigator.SceneConfigs.PushFromRight;
}}
renderScene={(route,navigator)=>{
let Component = route.component;
return <Component {...route.passProps} navigator={navigator}/>;
}}
/>
代码示例
- 注意事项:
- iOS中通常是
UITabBarController + UINavigationController +Controller
实现选项卡与导航条,self.hidesBottomBarWhenPushed = YES
实现隐藏二级界面tabBar
。 - RN中用iOS的思路则不能隐藏
tabBar
,是navigator -> tabBar -> component (tabBar当做普通组件)
- iOS中通常是
- Navigator
-
创建
NavigatorComponent
组件作为app入口,配置路由import React,{Component} from 'react'; import { View, Text, StyleSheet } from 'react-native'; /** * navigator ---命令行:'npm install react-native-deprecated-custom-components --save' */ import {Navigator} from "react-native-deprecated-custom-components"; import TabBar from './MainComponent' export default class NavigatorComponent extends Component{ render(){ return( //有导航功能,没有类似iOS的导航条,二级界面隐藏 tabBar <Navigator style={styles.container} initialRoute = {* name: 'TabBar', component: TabBar }} configureScene={()=>{ return Navigator.SceneConfigs.PushFromRight; }} renderScene={(route,navigator)=>{ let Component = route.component; return <Component {...route.passProps} navigator={navigator}/>; }} /> ); } } const styles = StyleSheet.create({ container:{ flex:1 } });
-
- TabBar
-
创建MainComponent组件作为TabBar,分别导入首页,我的等等组件
import React,{Component} from 'react'; import { View, Text, Image, StyleSheet, Platform,// 判断当前运行的系统 } from 'react-native'; /** * 导入第三方组件 * 1,tabBar---- 命令行:'npm install react-native-tab-navigator --save' */ import TabNavigator from 'react-native-tab-navigator'; /** * 导入根组件 */ import Home from '../Home/HomeComponent' import Shop from '../Shop/ShopComponent' import More from '../More/MoreComponent' import Mine from '../Mine/MineComponent' // iOS思路: tabBar -> navigation -> contorller // rn思路: navigator -> tabBar -> component (tabBar当做普通组件) export default class MainComponent extends Component{ // 状态机,记录选中的组件 constructor(props){ super(props); this.state={ selectTab:'home' } } render(){ return( <TabNavigator> {/*首页*/} {this._renderTabBarItem('首页','home','icon_tabbar_homepage','icon_tabbar_homepage_selected','首页',Home)} {/*商家*/} {this._renderTabBarItem('商家','shop','icon_tabbar_merchant_normal','icon_tabbar_merchant_selected','商家',Shop)} {/*我的*/} {this._renderTabBarItem('我的','mine','icon_tabbar_mine','icon_tabbar_mine_selected','我的',Mine)} {/*更多*/} {this._renderTabBarItem('更多','more','icon_tabbar_misc','icon_tabbar_misc_selected','更多',More)} </TabNavigator> ); } // 抽出创建TabNavigator方法 _renderTabBarItem(itemTitle,selectTabName,normalName,selectedName,componentName,component){ return( <TabNavigator.Item title={itemTitle} selectedTitleStyle={styles.selectedTitleStyle} selected={this.state.selectTab=== selectTabName} renderIcon={()=><Image source={*uri:normalName}} style={styles.iconStyle}/>} renderSelectedIcon={()=><Image source={*url:selectedName}} style={styles.iconStyle}/>} onPress={()=>{ this.setState({ selectTab:selectTabName }) }} > {this._renderComponent(selectTabName)} </TabNavigator.Item> ); } _renderComponent(index){ if (index==='home'){ return(<Home navigator={this.props.navigator}/>); } else if (index === 'shop'){ return(<Shop navigator={this.props.navigator}/>); } else if (index === 'mine'){ return(<Mine navigator={this.props.navigator}/>); } else { return(<More navigator={this.props.navigator}/>); } } } const styles = StyleSheet.create({ iconStyle:{ width: Platform.OS === 'ios'? 25:20, height:Platform.OS === 'ios'? 25:20, }, selectedTitleStyle:{ color:'orange' } });
-