跨平台开发RN-组件Navigator

  1. 作用:处理应用程序中不同场景之间的转换。
  2. 特点:
    1. 是跨平台的导航组件,不管在 iOS 还是 Android 系统下都能使用。
    2. 注意:默认没有包含导航栏,我们可以实现一个自定义导航栏,也可以使用 NavigatorBar 组件来实现
  3. Navigator安装
    1. 从0.44版本开始,Navigator被从react native的核心组件库中剥离到了一个名为react-native-deprecated-custom-components的单独模块中
    2. 导入navigator
      1. 打开终端,cd 到你的文件目录

         // 导入navigator
         npm  install   react-native-deprecated-custom-components  --save
        
  4. 两个核心要素
    1. navigator: 一个用来管理所有界面对象的栈,人称之为“路由栈”,也叫导航
    2. route: 路由栈里的每一个对象,称之为“路由”,用来存储每一个页面组件以及一些需要传递给对应界面的props参数

常用的属性

  1. initialRoute ={* name: name, component: component }}
    1. 这个指定了默认的页面,也就是启动的组件页面
    2. 初始路由,也就是我们需要在navigator栈底放置的路由,因此此时也是栈顶,因此也就是初始化整个APP的首页
  2. configureScene 设置页面跳转样式
    1. configureScene函数应该返回一个场景配置对象用来定义页面切换的动画。可用场景配置选项为:

       PushFromRight(默认)
       FloatFromRight
       FloatFromLeft
       FloatFromBottom
       FloatFromBottomAndroid
       FadeAndroid
       SwipeFromLeft
       HorizontalSwipeJump
       HorizontalSwipeJumpFromRight
       HorizontalSwipeJumpFromLeft
       VerticalUpSwipeJump
       VerticalDownSwipeJump
      
    2. 使用:

        configureScene ={() => {
        return Navigator. SceneConfigs .HorizontalSwipeJump;
        }}
      
  3. renderScene
    1. 具体是方法如下:

       renderScene={(route,navigator)=>{
           let Component = route.component;
           return <Component {...route.passProps} navigator={navigator}/>;
           }}
       />
      
    2. 渲染当前路由场景,就是说渲染出路由栈中栈顶(将要显示)的那个组件,回调方法中的参数:
      1. route: 当前路由
      2. navigator: 路由栈
    3. ...route: 是一个ES6的语法,表示将路由route中所有的键值对以属性赋值的方式展开,也就是{name:'poper',gender:'man'}name='poper',gender='man'转化,这样就把route对象中所有的键值对,就很容易的放到route.component组件的props属性中去;因此,这个语法在自定义控件的时候也经常用到,主要用来兼容组件中其他所有属性,如自定义ListView兼容官方LsitView所有属性。
    4. 两个参数中的route包含的是initial的时候传递的name和component,而navigator是一个我们需要用的Navigator的对象;
    5. 所以当我们拿到route中的component的时候,我们就可以将navigator传递给它,正因为如此,我们的组件HomeScene才可以通过 this.props.navigator,拿到路由。
  4. initialRouteStack [object] 参数对象数组
    1. 这是一个初始化的路由数组进行初始化。如果initalRoute属性没有设置的话,那么就必须设置initialRouteStack属性,使用该最后一项作为初始路由。 如果initalRouteStack属性没有设置的话,该会生成只包含initalRoute值的数组
  5. navigationBar node
    1. 该为可选的参数,在页面切换中用来提供一个导航栏
  6. navigator object
    1. 该为可选参数,可以从父类导航器中获取导航器对象
  7. sceneStyle 样式风格
    1. 该继承了View视图的所有样式风格,用于设置每个页面容器的风格
  8. onWillFocus:
    1. 每个navigator组件转换之前,会回调onWillFocus函数。
  9. onDidFocus:
    1. 每个navigator组件转换之后,会回调onDidFocus函数。

常用的导航器方法

  1. 当获取了导航器对象的引用,我们可以进行调用以下一些方法来实现页面导航功能:
  2. 如下:
    1. getCurrentRoutes()
      1. 该进行返回存在的路由列表信息
    2. jumpBack()
      1. 该进行回退操作 但是该不会卸载(删除)当前的页面
    3. jumpForward()
      1. 进行跳转到相当于当前页面的下一个页面
    4. jumpTo(route)
      1. 根据传入的一个路由信息,跳转到一个指定的页面(该页面不会卸载删除)
    5. push(route)
      1. 导航切换到一个新的页面中,新的页面进行压入栈。通过jumpForward()方法可以回退过去
    6. pop()
      1. 当前页面弹出来,跳转到栈中下一个页面,并且卸载删除掉当前的页面
    7. replace(route)
      1. 只用传入的路由的指定页面进行替换掉当前的页面
    8. replaceAtIndex(route,index)
      1. 传入路由以及位置索引,使用该路由指定的页面跳转到指定位置的页面
    9. replacePrevious(route)
      1. 传入路由,通过指定路由的页面替换掉前一个页面
    10. resetTo(route)
      1. 进行导航到新的界面,并且重置整个路由栈
    11. immediatelyResetRouteStack(routeStack)
      1. 该通过一个路由页面数组来进行重置路由栈
    12. popToRoute(route)
      1. 进行弹出相关页面,跳转到指定路由的页面,弹出来的页面会被卸载删除
    13. popToTop()
      1. 进行弹出页面,导航到栈中的第一个页面,弹出来的所有页面会被卸载删除

默认写法

<Navigator
initialRoute = {* name: defaultName, component: defaultComponent }}
configureScene={()=>{
    return Navigator.SceneConfigs.PushFromRight;
}}
renderScene={(route,navigator)=>{
    let Component = route.component;
    return <Component {...route.passProps} navigator={navigator}/>;
    }}
/>

代码示例

  1. 注意事项:
    1. iOS中通常是UITabBarController + UINavigationController +Controller 实现选项卡与导航条,self.hidesBottomBarWhenPushed = YES实现隐藏二级界面tabBar
    2. RN中用iOS的思路则不能隐藏tabBar,是navigator -> tabBar -> component (tabBar当做普通组件)
  2. Navigator
    1. 创建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
           }
       });
      
  3. TabBar
    1. 创建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'
           }
       });
      
Table of Contents