基础篇章:关于 React Native 之 Navigator 组件的讲解

(友情提示:RN学习,从最基础的开始,大家不要嫌弃太基础,会的同学请自行略过,希望不要耽误已经会的同学的宝贵时间)

今天我们来讲讲Navigator这个小家伙,呃……不能说小家伙,因为它还是很厉害的,有了它我就就能实现各个界面的跳转和切换。所以它的名字叫导航器。来,今天我们就一起来学习学习它。

使用我Navigator可以让你们实现在应用内不同页面的切换,我是用JavaScript实现的,而且我有两个:IOS和Android,如果在IOS上使用请用我的双胞胎兄弟NavigatorIOS,因为它充分利用本地的UIKit导航。

要想设置Navigator,使用我,你们必须确定一个或多个调用routes对象,去定义每个场景。你们还可以利用renderScene方法,导航栏可以根据指定的路由来渲染场景。

官网基础小例子

render() {
  const routes = [
    {title: 'First Scene', index: 0},
    {title: 'Second Scene', index: 1},
  ];
  return (
    <Navigator
      initialRoute={routes[0]}
      initialRouteStack={routes}
      renderScene={(route, navigator) =>
        <TouchableHighlight onPress={() => {
          if (route.index === 0) {
            navigator.push(routes[1]);
          } else {
            navigator.pop();
          }
        }}>
        <Text>Hello {route.title}!</Text>
        </TouchableHighlight>
      }
      style={{padding: 100}}
    />
  );
}

nitialRoute 在上面的示例中,initialRoute 用于指定的第一个路由。它包含一个标题属性,标识路由。RenderScene 属性返回一个函数,显示路由标题文本。 initialRouteStack initialRoute指定第一个显示的页面,而要设置多个场景,你们通过initialRouteStack属性了。通过上面例子,我们可以看到定义了两个路由,而且每个路由都有一个用于管理被渲染场景的索引属性。在renderScene方法中有一个触摸事件,触摸决定导航器是推或者弹出哪个导航场景。

Navigation Bar

我们可以在Navigator上设置标题导航栏Navigation Bar,在标题导航栏中我们可以通过routeMapper属性去设置左,右和标题导航栏。在配置左,右,和标题导航栏项目,您可以访问信息,如当前路由对象和导航状态。这使您可以为每个场景自定义标题以及按钮。例如,您可以选择隐藏场景中的左键。 例子如下:

<Navigator
  renderScene={(route, navigator) =>
    // ...
  }
  navigationBar={
     <Navigator.NavigationBar
       routeMapper={{
         LeftButton: (route, navigator, index, navState) =>
          { return (<Text>Cancel</Text>); },
         RightButton: (route, navigator, index, navState) =>
           { return (<Text>Done</Text>); },
         Title: (route, navigator, index, navState) =>
           { return (<Text>Awesome Nav Bar</Text>); },
       }}
       style={{backgroundColor: 'gray'}}
     />
  }
/>

场景转换

要想改变场景的动画和转换,相当于我们Android中的进场和转场动画,我们可以通过configureScene属性来获得对于给定路线的配置对象。如下:

<Navigator
  renderScene={(route, navigator) =>
    // ...
  }
  configureScene={(route, routeStack) =>
    Navigator.SceneConfigs.FloatFromBottom}
/>

属性

  • configureScene function 就是通过它配置场景转换的。它有如下属性:
    • Navigator.SceneConfigs.PushFromRight (default)
    • Navigator.SceneConfigs.FloatFromRight
    • Navigator.SceneConfigs.FloatFromLeft
    • Navigator.SceneConfigs.FloatFromBottom
    • Navigator.SceneConfigs.FloatFromBottomAndroid
    • Navigator.SceneConfigs.FadeAndroid
    • Navigator.SceneConfigs.HorizontalSwipeJump
    • Navigator.SceneConfigs.HorizontalSwipeJumpFromRight
    • Navigator.SceneConfigs.VerticalUpSwipeJump
    • Navigator.SceneConfigs.VerticalDownSwipeJump
  • initialRoute object 定义启动时加载的路由。路由是导航栏用来识别渲染场景的一个对象。initialRoute必须是initialRouteStack中的一个路由。initialRoute默认为initialRouteStack中最后一项。
  • initialRouteStack [object] 存放路由的一个数组
  • navigationBar node 上面介绍了
  • navigator object
  • onDidFocus function 每当导航切换完成或初始化之后,调用此回调,参数为新场景的路由
  • onWillFocus function 会在导航切换之前调用,参数为目标路由
  • renderScene function 用来渲染每一个路由指定的页面
  • sceneStyle 样式风格

方法

  • immediatelyResetRouteStack(nextRouteStack) 用新的路由数组来重置路由栈
  • jumpTo(route) 跳转到传入的已有的场景并且不卸载
  • jumpForward(0) 跳转到下一个场景
  • jumpBack(0) 同上相反的意思
  • push(route) 跳转到新的场景,并且将场景入栈,你可以稍后用jump forward 跳转回去
  • popN(n) 回到ñ场景一次。当N = 1,行为相匹配pop()方法。当N是无效的(负或大于当前的路线计算),什么也不做。
  • pop(0) 跳转回去并且卸载掉当前场景
  • replaceAtIndex(route, index, cb) 替换掉指定序列的路由场景
  • replace(route) 用一个新路由替换当前场景
  • replacePrevious(route) 替换掉之前的场景
  • popToTop(0) pop到栈中的第一个场景,卸载掉所有的其他场景
  • popToRoute(route) pop到路由指定的场景,在整个路由栈中,处于指定场景之后的场景将会被卸载
  • replacePreviousAndPop(route) 取代之前的场景,并弹出它
  • resetTo(route) 跳转到指定的新场景,并重置路由栈
  • getCurrentRoutes() 获取当前栈里的路由

实例

效果图

怎么样?我的样子很帅吧,是不是很想和我玩,那就赶紧行动起来吧,我已经迫不及待的想跟你们一起玩了。来看看怎么和我玩的实例代码吧。

代码

import React, { Component } from 'react';
import {
  AppRegistry,
  StyleSheet,
  Text,
  Navigator,
  Image,
  TouchableHighlight,
  TouchableOpacity,
  View
} from 'react-native';

NavigationBarRouteMapper = {
   LeftButton(route, navigator, index, navState) {
     if (route.id === 'first') {
       return null;
     }
     previousRoute = navState.routeStack[index - 1];
     return (
       <TouchableOpacity
         onPress={() => navigator.pop()}
         style={styles.navBarLeftButton}>
         <Image source={require('./back.png')} style={styles.backImage}>
         </Image>
       </TouchableOpacity>
     );
   },
   RightButton(route, navigator, index, navState) {
     if (route.id === 'second') {
       return null;
     }
     return (
       <TouchableOpacity
         onPress={() => navigator.push({id:'second',title:'第二页',data:"我是从第一页跳转过来的"})}
         style={styles.navBarRightButton}>
         <Text style={[styles.navBarButtonText]}>
           下一页
         </Text>
       </TouchableOpacity>
     );
   },

   Title(route, navigator, index, navState) {
     return (
       <Text style={[styles.navBarTitleText]}>
         {route.title}
       </Text>
     );
   },
 };

export default class NavigatorDemo extends Component {
   render(){
      return (
        <Navigator
          style = {styles.container}
          initialRoute={{id:"first",title:"第一页"}}
          renderScene={this.renderNav}
          configureScene={(route, routeStack) => Navigator.SceneConfigs.HorizontalSwipeJump}
          navigationBar={
            <Navigator.NavigationBar
              routeMapper={NavigationBarRouteMapper}
              style={{backgroundColor:'white'}}
           />
          }
          />
      );
    }

    renderNav(route,nav){
        switch (route.id) {
          case 'first':
            return <FirstScreen navigator={nav} title="第一页"/ >;
          case 'second':
            return (<SecondScreen navigator={nav} title="第二页" data={route.data}/>);
        }
    }
}

class FirstScreen extends Component{
   toSecond=()=>{
     this.props.navigator.push({id:"second",title:"第二页",data:"我是第二页"});
  }
   render(){
     return (
       <View style={styles.firstView}>
         <TouchableHighlight
          style={{padding:10}}
          onPress={this.toSecond}
          underlayColor="blue">
            <Text style={styles.contentText}>第一页</Text>
         </TouchableHighlight>
       </View>
     );
   }
 }

class SecondScreen extends Component{
   toFirst=()=>{
     this.props.navigator.pop();
   }
   render(){
     return (
       <View style={styles.secondView}>
         <TouchableHighlight
          style={{padding:10}}
          onPress={this.toFirst}
          underlayColor="red">
            <Text style={styles.contentText}>{this.props.data}</Text>
         </TouchableHighlight>
       </View>
     );
   }
 }

const styles = StyleSheet.create({
   backImage:{
     width:15,
     height:30,
   },
  navBarTitleText: {
    color: 'black',
    fontWeight: '500',
    marginTop:20,
  },
  navBarLeftButton: {
    paddingLeft: 10,
    paddingTop:15,
  },
  navBarRightButton: {
    paddingRight: 10,
    paddingTop:20,
  },
  navBarButtonText: {
    color: '#5890FF',
  },
   container: {
     flex: 1,
   },
   firstView:{
     flex: 1,
     backgroundColor:'red',
     justifyContent: 'center',
   },
   secondView:{
     flex:1,
     justifyContent: 'center',
     backgroundColor:'blue',
   },
   contentText:{
     fontSize:22,
     color:'white',
     textAlign:'center',
   },
});

AppRegistry.registerComponent('NavigatorDemo', () => NavigatorDemo);

原文发布于微信公众号 - 非著名程序员(non-famous-coder)

原文发表时间:2016-11-13

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏Alice

ios tableview 上加 textfiled

ios tableview 上加 textfiled  首先附上我项目中用曾经用到的几张图  并说明一下我的用法: 图1: ? 图2: ? 图3: ? 心在你我...

24750
来自专栏CRPER折腾记

React 折腾记 - (3) 结合Mobx实现一个比较靠谱的动态tab水平菜单,同时关联侧边栏

48020
来自专栏CRPER折腾记

React 折腾记 - (4) 侧边栏联动Tabs菜单-增强版(结合Mobx)

上个版本 :React 折腾记 - (3) 结合Mobx实现一个比较靠谱的动态tab水平菜单,同时关联侧边栏

52630
来自专栏施炯的IoT开发专栏

《101 Windows Phone 7 Apps》读书笔记-Weight Tracker

课程内容 Ø Charts & Graphs     你平时关注自己的体重吗?Weight Tracker使得你可以随时跟踪自己的体重,并且提供几种体重发展趋...

20180
来自专栏有趣的django

博客园美化终极版-(自定义导航栏)----什么CSDN、简书、腾讯云专栏、个人博客和微信公众号都弱爆了

75700
来自专栏糊一笑

移动端效果之ScrollList

写在前面 列表一直是展示数据的一个重要方式,在手机端的列表展示又和PC端展示不同,毕竟手机端主要靠滑。之前手机端之前一直使用的IScroll,但是IScroll...

28360
来自专栏一“技”之长

iOS文本布局探讨之三——使用TextKit框架进行富文本布局

        关于图文混排,其实以前的博客已经讨论很多,在实际开发中,经常使用第三方的框架来完成排版的需求,其中RCLabel和RTLabel是两个比较好用的...

15220
来自专栏一“技”之长

iOS开发中的手势体系——UIGestureRecognizer分析及其子类的使用

        在iOS系统中,手势是进行用户交互的重要方式,通过UIGestureRecognizer类,我们可以轻松的创建出各种手势应用于app中。关于UI...

8120
来自专栏Material Design组件

Human Interface Guidelines —— Pickers

11120
来自专栏xx_Cc的学习总结专栏

六天完成一个简单iOS App - 第一天

30650

扫码关注云+社区

领取腾讯云代金券