使用react-navigation进行简单的跳转+底部导航栏+侧拉框的配置

使用react native进行开发,不可避免的会使用到跳转。鉴于目前react native版本问题。一般使用react-navigation实现跳转。这也是官方推荐使用的组件。

createStackNavigator  为您的应用提供一种在屏幕之间转换的方式,其中每个新屏幕都放置在堆栈顶部。这个是我们实现跳转所要使用到的API。它的用法

createStackNavigator(RouteConfigs, StackNavigatorConfig);

RouteConfigs参数,我们用来写路由相关的配置。一般我们写具有跳转关系的View配置。比如,有A、B、C三个页面,我需要A、B、C三个页面同时具有跳转关系。即我可以从A跳转至B,亦可以从A跳转至C,B跳转至C等同级跳转。我们将A、B、C注册到RouteConfigs参数,同时,我们可以对这些页面进行一些样式操作。默认页面会有标题栏,返回按钮等样式。如果不需要,我们可以将其去除等操作。总而言之,我们可以用来注册我们期望具有跳抓功能的View页面

StackNavigatorConfig参数,用来设置一些跳转的默认操作,比如堆栈的默认屏幕视图,初始路线的参数等设置,按照需求进行设置,不过多做讲解。

const HomeStack = createStackNavigator({//设置HomeScreen页面与SettingView页面的跳转注册
  HomeScreen: {
    screen: HomeScreen,//注册View页面名称
    navigationOptions: () => ({
      header: null, //去除标题栏
      headerBackTitle: null, //去除返回按钮
      gesturesEnabled: true  //是否可以使用手势来关闭此屏幕。在iOS上默认为true,在Android上默认为false
    })
  },
  SettingView: {//注册设置页面
    screen: SettingView,
    navigationOptions: () => ({
      header: null, //去除标题栏
      headerBackTitle: null, //去除返回按钮
      gesturesEnabled: true  //是否可以使用手势来关闭此屏幕。在iOS上默认为true,在Android上默认为false
    })
  },
  MapScreen: {//注册地图页面
    screen: MapScreen,
    navigationOptions: () => ({
      header: null, //去除标题栏
      headerBackTitle: null, //去除返回按钮
      gesturesEnabled: true  //是否可以使用手势来关闭此屏幕。在iOS上默认为true,在Android上默认为false
    })
  },
  DetailInfo: {//注册业务详情页面
    screen: DetailInfo,
    navigationOptions: () => ({
      header: null, //去除标题栏
      headerBackTitle: null, //去除返回按钮
      gesturesEnabled: true  //是否可以使用手势来关闭此屏幕。在iOS上默认为true,在Android上默认为false
    })
  },
  Appointment: {//注册业务列表页面
    screen: Appointment,
    navigationOptions: () => ({
      header: null, //去除标题栏
      headerBackTitle: null, //去除返回按钮
      gesturesEnabled: true  //是否可以使用手势来关闭此屏幕。在iOS上默认为true,在Android上默认为false
    })
  }
},{
  initialRouteName:'HomeScreen',
  initialRouteParams:{ //设置初始参数
    key:'aaaaa',
    key1:'bbbbb'
  },
});

注意:createStackNavigator与createSwitchNavigator的区别。它两个作用大致相同。createStackNavigator具有堆栈功能,createSwitchNavigator不具有堆栈功能,createSwitchNavigator的目的是一次只显示一个屏幕。默认情况下,它不处理后退操作,并在您切换时,将路由重置为其默认状态。这是我们从身份验证流程中想要的确切行为。

我们进行了跳转配置后,当然就是如何使用了。

screen您应用中的每个组件都会navigation自动提供道具。prop包含各种便利功能,用于在路由的路由器上分派导航操作。

进行跳转的API https://reactnavigation.org/docs/en/navigation-prop.html

this.props.navigation
    navigate - 转到另一个屏幕,找出它需要采取的行动
    goBack - 关闭活动屏幕并向后移动
    addListener - 订阅导航生命周期的更新
    isFocused- true如果屏幕聚焦false则返回的功能
    state - 当前路线
    setParams - 改变路线的参数,传递参数
    getParam - 获得具有后备的特定参数,获取参数
    dispatch - 向路由器发送动作
    dangerouslyGetParent - 返回父导航器的函数(如果有)

简单举例

我们可以使用this.props.navigation.navigate('要跳转的View名称')方式进行跳转,该跳转方式,会将跳转的页面存入栈顶部,当点击返回按键,或者调用this.props.navigation.goBack()方法时返回到上个页面。

我们如果想要回退到指定的页面,我们需要得到我们将要回退页面上一个页面的页面key进行回退,调用this.props.navigation.goBack(key)方式回退到指定的页面。

比如,有A、B、C、D四个页面。我从A使用this.props.navigation.navigate('B')跳转到了B页面,然后使用this.props.navigation.navigate('C')跳转到了C页面,然后又跳转到D页面,但是我想直接返回到A页面,如果我按返回键,则返回顺序是D > C > B > A。不是我想要的结果。我如果之间使用this.props.navigation.navigate('A')的方式跳转到A,那么我退出时,会出现A > D > C > B > A。这种情况(当然,有双击退出,强制退出操作不在考虑范围内),设计不太合理。我们可以使用this.props.navigation.goBack(key)这种方式进行返回,我们首先要得到我们要返回的页面的前一个页面的页面KEY,也就是A前面的页面B页面的KEY。

let HOME_KEY = this.props.navigation.state.key;//得到当前页面key

使用以上方式得到页面key后传入到D页面中的this.props.navigation.goBack(key)函数中。我们就能够返回到原页面。

使用this.props.navigation.navigate()方法也可以进行传值。

this.props.navigation.navigate('A', {
                    session: this.state.session,
                    ucid: this.state.ucid,
                });

取值,包括初始化页面时的传递的初始值,也可以以这种方式取值

 const { navigation } = this.props;
        let value = navigation.getParam('key', '');  //得到Drawer页面传递的页面key
        let value1 = navigation.getParam('key1', '');  //得到Drawer页面传递的页面key

底部导航栏 createBottomTabNavigator  react-navigation为我们提供了底部导航栏与顶部导航栏的API,我们只做底部导航栏的讲解。

createBottomTabNavigator(RouteConfigs, BottomTabNavigatorConfig);

它同样有两个参数。RouteConfigs用法与createStackNavigator用法一样,不做讲解。但是,我们会将底部导航所需的View放在次参数中,因为,底部导航至少会有两个页面。

{//RouteConfigs
  Home: {
    screen: HomeStack,
  },
  Work: {
    screen: WorkStack,
  },
}

BottomTabNavigatorConfig,我们用来做一些底部导航栏样式的一些操作,比如,我们所点击的图标,图标颜色(选中状态颜色,未选中状态颜色),图标下方的字体等等。都在代码中添加了注释

//配置底部导航栏(标签栏),HomeScreen与WorkScreen页面
const bottomTabNavigator = createBottomTabNavigator({//RouteConfigs
  Home: {
    screen: HomeStack,
  },
  Work: {
    screen: WorkStack,
  },
}, {//BottomTavNavtigtorConfig
    defaultNavigationOptions: ({ navigation }) => ({ //用于屏幕的默认导航选项
      tabBarIcon: ({ focused, tintColor }) =>   //设置图标
        getTabBarIcon(navigation, focused, tintColor),
      tabBarLabel: navigation.state.routeName === 'Home' ? '首页' : '工作',  //设置图标下方的字体
    }),
    tabBarOptions: { //设置图标的样式
      activeTintColor: '#1E90FF',  //活动选项卡的标签和图标颜色。选中时颜色
      inactiveTintColor: '#979797'  //非活动选项卡的标签和图标颜色。 未选中时颜色
    },
  });


//设置底部图片以及图片的状态改变
const getTabBarIcon = (navigation, focused, tintColor) => {  //设置图标默认状态
  const { routeName } = navigation.state;
  if (routeName === 'Home') { //设置点击Home页面时,图标状态
    return <Image style={{  //图标的样式
      width: 25,
      height: 25
    }}
      source={focused ? require('./image/tabbar_home_pressed.png') : require('./image/tabbar_home.png')} />  //返回选中与未选中不同状态时,图标的样式,颜色
  } else if (routeName === 'Work') { //设置点击Work页面时,图标状态
    return <Image style={{ ////图标的样式
      width: 25,
      height: 25
    }}
      source={focused ? require('./image/tabbar_msg_pressed.png') : require('./image/tabbar_msg.png')} />  //返回选中与未选中不同状态时,图标的样式,颜色
  }
};

侧拉框 createDrawerNavigator  

createDrawerNavigator(RouteConfigs, DrawerNavigatorConfig);

同样的,俩个参数RouteConfigs, DrawerNavigatorConfig。

RouteConfigs

路由CONFIGS对象是从路由名称映射到一个路由配置,它告诉导航以呈现该路线什么。我们一般用来写侧拉框所在的页面。

{//RouteConfigs
  Set: {//Set是固定名称
    screen: bottomTabNavigator,
  },
}

DrawerNavigatorConfig,用来配置侧拉框抽屉的一些默认设置

{
    order: ['Set'],//routeNames数组,用于定义抽屉项目的顺序。
    initialRouteName: 'Set',//初始路由的routeName。
    drawerLockMode: 'unlocked',//设置是否响应手势
    //'unlocked'   可以通过手势和代码 打开关闭抽屉
    //'locked-closed' 抽屉关闭状态  不能通过手势打开  只能通过代码实现
    //'locked-open'  抽屉打开状态  不能通过手势关闭  只能通过代码实现

    drawerWidth: 300, //抽屉的宽度或返回的功能。
    drawerPosition: 'left', //选项是left或right。默认是left位置。
    useNativeAnimations: true, //启用原生动画。默认是true。
    drawerBackgroundColor: '#FAFAFA', //使用抽屉背景获取某种颜色。默认是white。
    //用于呈现抽屉内容的组件,例如导航项。收到navigation抽屉的道具。默认为DrawerItems
    //用于自定义
    contentComponent: props => {
      return <Drawer {...props} />;
    },
    //配置抽屉内容  items相关
    contentOptions: {
      // items: [OtherScreen],//可以修改或覆盖路由数组  不知道干嘛用的
      // activeItemKey: 'AppInfo', //识别活动路线的关键  也不知道干嘛用的
      activeTintColor: 'white', //活动标签的标签和图标颜色
      activeBackgroundColor: 'blue', //活动标签的背景颜色
      inactiveTintColor: 'black', //非活动标签的标签和图标颜色
      inactiveBackgroundColor: 'red', //非活动标签的背景颜色

      // //按下项目时要调用的函数 不知道是否使用错误 一直没反应
      //github上面有答案 在自定义视图的时候 会有用
      // onItemPress(route) {
      //     console.log('onItemPress'+route);
      // },

      // itemsContainerStyle: '', //内容部分的样式对象
      // itemStyle: '', //单个项目的样式对象,可以包含图标和 / 或标签
      // labelStyle: '', //Text当标签是字符串时,样式对象在内容部分内覆盖样式
      // activeLabelStyle: '', //Text当标签是字符串(与之合并labelStyle)时,样式对象覆盖活动标签的样式
      // inactiveLabelStyle: '', //Text当标签是字符串(与之合并labelStyle)时,样式对象覆盖非活动标签的样式
      // iconContainerStyle: '', //样式对象以覆盖View图标容器样式。
    }

  }

重点:

//用于自定义
    contentComponent: props => {
      return <Drawer {...props} />;
    },

我们用该方法,可以将抽屉视图进行自定义。也就是说。我们可以在此页面编写抽屉视图。Drawer就是我的抽屉页面的视图。完全可以按照自己想要的效果进行布局。

this.props.navigation.openDrawer();//打开抽屉
this.props.navigation.closeDrawer();//关闭抽屉

我们可以在抽屉所在的页面中调用以上方法,进行打开或者关闭抽屉的动作。当然,也可以滑动屏幕来打开或关闭抽屉。

关于react-navigation的使用,我还远远未发掘出来,这只是它的一部分,包括它的生命周期,与RN的生命周期的对应,对于它的生命周期的处理。不过,这已经足够开发出一个优秀的App了。希望以后会更加熟练的使用react-navigation吧。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章