当前位置: 永利皇宫463手机版 > Web前端 > 正文

ReactNative学习执行,使用导航Navigator

时间:2019-11-14 17:43来源:Web前端
ReactNative学习施行:Navigator执行 2016/06/17 · JavaScript· HTML5,Javascript,React,ReactNative 本文小编: 伯乐在线 -D.son。未经作者许可,制止转发! 应接参与伯乐在线 专栏作者。 离上次写TiggoN笔记

ReactNative学习施行:Navigator执行

2016/06/17 · JavaScript · HTML5, Javascript, React, ReactNative

本文小编: 伯乐在线 - D.son 。未经作者许可,制止转发!
应接参与伯乐在线 专栏作者。

离上次写TiggoN笔记有风流洒脱段时间了,时期参预了二个新类型,只在明日的空闲时间继续上学实行,由此进程正如缓慢,可是那并不代表未有新进展,其实这一个小东西离上次发布公文时风姿潇洒度有了相当大的变通了,个中国电影响最大的改变便是引进了Redux,前面会系统介绍一下。
在起头宗旨在此以前,先增补某个上回聊起的动漫片初探(像自家那样可信赖严俊的工程师,必需校订,┗|`O′|┛ 嗷~~)。

上回文提及,经过我们团结定义了余弦动漫函数之后,动态设定state的4个参数,完成了相比较通畅的加载动漫,这里或然有意中人已经注意到了,大家丰盛频仍的调用了setState方法,那在React和奥德赛N中都以豆蔻梢头对一隐讳的,每次setState都会触发render方法,也就表示更频仍的虚构DOM相比较,特别是在ENCOREN中,这还意味着更频繁的JSCore<==>iOS通信,固然框架本人对屡次setState做了优化,比如会计统计一同期调用的三个setState,但那对品质和心得还是会有一点都不小影响。

上回大家只是独自实现了一个loading动漫,所以还比较通畅,当视图八月素非常多並且有独家的卡通片的时候,就能够看出相比较严重的卡顿,那些实际上是能够制止的,因为在loading动漫的兑现部分,大家精晓地知道只供给loading动漫的一定组成都部队分更新并不是组件的具备片段以至世袭链上的具备组件都亟需立异,並且确信这一个节点确定产生了变化,由此不须求通过设想DOM比较,那么只要我们能绕开setState,动漫就活该会更流畅,尽管在纷纭的视图里边。那便是Animations文书档案最后提到的setNativeProps方法。

As mentioned in the Direction Manipulation section, setNativeProps allows us to modify properties of native-backed components (components that are actually backed by native views, unlike composite components) directly, without having to setState and re-render the component hierarchy.

setNativeProps允许大家直接决定原生组件的性质,而不须要用到setState,也不会重绘袭承链上的此外构件。那多亏大家想要的功效,加上大家分明通晓正在调控的组件以致它与视图其余构件的涉嫌,因而,这里大家能够放心地应用它,并且一定轻松。
更新前:

loopAnimation(){ var t0=animationT,t1=t0+0.5,t2=t1+0.5,t3=t2+timeDelay,t4=t3+0.5;//这里分别是多少个卡通的一时一刻岁月,依次增进了0.5的延期 var v1=Number(Math.cos(t0).toFixed(2))*animationN+animationM;//将cos函数的小数值只准确到小数点2位,提升运算成效var v2=Number(Math.cos(t1).toFixed(2))*animationN+animationM; var v3=Number(Math.cos(t2).toFixed(2))*animationN+animationM; var v4=Number(Math.cos(t3).toFixed(2))*animationN+animationM; this.setState({ fV:v1, sV:v2, tV:v3, foV:v4 }); animationT+=0.35;//扩展时间值,每一次增值越大动漫越快 requestAnimationFrame(this.loopAnimation.bind(this)); }

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
loopAnimation(){
    var t0=animationT,t1=t0+0.5,t2=t1+0.5,t3=t2+timeDelay,t4=t3+0.5;//这里分别是四个动画的当前时间,依次加上了0.5的延迟
    var v1=Number(Math.cos(t0).toFixed(2))*animationN+animationM;//将cos函数的小数值只精确到小数点2位,提高运算效率
    var v2=Number(Math.cos(t1).toFixed(2))*animationN+animationM;
    var v3=Number(Math.cos(t2).toFixed(2))*animationN+animationM;
    var v4=Number(Math.cos(t3).toFixed(2))*animationN+animationM;
    this.setState({
      fV:v1,
      sV:v2,
      tV:v3,
      foV:v4
    });
    animationT+=0.35;//增加时间值,每次增值越大动画越快
    requestAnimationFrame(this.loopAnimation.bind(this));
  }

更新后:

loopAnimation(){ var t0=··· var v1=··· var v2=··· var v3=··· var v4=··· this.refs.line1.setNativeProps({ style:{width:w1,height:v1} }); this.refs.line2.setNativeProps({ style:{width:w2,height:v2} }); this.refs.line3.setNativeProps({ style:{width:w3,height:v3} }); this.refs.line4.setNativeProps({ style:{width:w4,height:v4} }); animationT+=0.35;//扩展时间值,每一次增值越大动漫越快 requestAnimationFrame(this.loopAnimation.bind(this)); }

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
loopAnimation(){
    var t0=···
    var v1=···
    var v2=···
    var v3=···
    var v4=···
    this.refs.line1.setNativeProps({
      style:{width:w1,height:v1}
    });
    this.refs.line2.setNativeProps({
      style:{width:w2,height:v2}
    });
    this.refs.line3.setNativeProps({
      style:{width:w3,height:v3}
    });
    this.refs.line4.setNativeProps({
      style:{width:w4,height:v4}
    });
    animationT+=0.35;//增加时间值,每次增值越大动画越快
    requestAnimationFrame(this.loopAnimation.bind(this));
  }

效能如下:
图片 1
此间有意在注册诉求达成之后未有掩盖loading动漫,由此同不经常候试行了视图切换和loading五个卡通,效果还不错~

好了,该进入今日的主旨了。先全体看一下那大器晚成阶段落到实处的效应(哒哒哒~):
图片 2

重大是模拟了贰个新顾客注册流程,完毕起来也并不复杂,整体布局是用多个中华VN组件Navigator来做导航,即使有另一个NavigatorIOS组件在iOS系统上显现越来越完美,不过构思到ENCOREN自身希望能够同一时候在安卓和iOS上运营的初心,作者选取了能够匹配七个阳台的Navigator来品尝,如今来看作用还是能够承当。
在最终的详细音讯视图里边,尝试了种种零件,举个例子调用相机,Switch,Slider等,首倘若尝鲜,哈哈~ 也本身完结了比较轻便的check按键。
第后生可畏最外层的协会是一个Navigator,它调节总体客商注册的视图切换:

<Navigator style={styles.navWrap} initialRoute={{name: 'login', component:LoginView}} configureScene={(route) => { return Navigator.SceneConfigs.FloatFromRight; }} renderScene={(route, navigator) => { let Component = route.component; return <Component {...route.params} navigator={navigator} /> }} />

1
2
3
4
5
6
7
8
9
<Navigator style={styles.navWrap}
          initialRoute={{name: 'login', component:LoginView}}
          configureScene={(route) => {
            return Navigator.SceneConfigs.FloatFromRight;
          }}
          renderScene={(route, navigator) => {
            let Component = route.component;
            return <Component {...route.params} navigator={navigator} />
          }} />

里面,initialRoute配置了Navigator的起来组件,这里正是LoginView组件,它本人既可以够平素登陆,也得以点击【小编要登记】踏向注册流程。configureScene属性则是用来布署Navigator中央广播台图切换的动漫片类型,这里能够灵活布署切换情势:

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

1
2
3
4
5
6
7
8
9
10
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

renderScene属性则是必需配备的二个属性,它担负渲染给定路由相应的零件,约等于向Navigator全体路由对应的机件传递了”navigator”属性以至route本人指引的参数,即便不利用相符Flux只怕Redux来全局存款和储蓄或调整state的话,那么Navigator里多少的传递就全靠”route.params”了,譬喻客商注册流程中,首先是选拔剧中人物视图,然后踏入注册视图填写账号密码短信码等,这个时候点击注册才会将持有数据发送给服务器,由此从剧中人物选拔视图到注册视图,须要将顾客接收的剧中人物传递下去,在登记视图发送给服务器。由此,剧中人物接受视图的跳转事件需求把参数字传送递下去:

class CharacterView extends Component { constructor(props){ super(props); this.state={ character:"type_one" } } handleNavBack(){ this.props.navigator.pop(); } ··· handleConfirm(){ this.props.navigator.push({ name:"registerNav", component:RegisterNavView, params:{character:this.state.character} }); } render(){ return ( <View style={styles.container}> <TopBarView title="注册" hasBackArr={true} onBackPress={this.handleNavBack.bind(this)}/> ··· (this)}> 确认> </TouchableOpacity> > </View> ); } }

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
class CharacterView extends Component {
  constructor(props){
    super(props);
    this.state={
        character:"type_one"
    }
  }
 
  handleNavBack(){
    this.props.navigator.pop();
  }
  
  ···
  
  handleConfirm(){
    this.props.navigator.push({
      name:"registerNav",
      component:RegisterNavView,
      params:{character:this.state.character}
    });
  }
 
  render(){
    return (
      <View style={styles.container}>
        <TopBarView title="注册" hasBackArr={true} onBackPress={this.handleNavBack.bind(this)}/>
        
          
          ···
          
          (this)}>
            确认>
          </TouchableOpacity>
        >
      </View>
    );
  }
}

那是角色选取视图CharacterView的部分代码,由于Navigator并从未像NavigatorIOS那样提供可配置的顶栏、重临开关,所以本人把顶栏做成了贰个克配置的共用组件TopBarView,Navigator里边的兼具视图直接使用就能够了,点击TopBarView的回来按键时,TopBarView会调用给它配置的onBackPress回调函数,这里onBackPress回调函数是CharacterView的handleNavBack方法,即实施了:

this.props.navigator.pop();

1
this.props.navigator.pop();

关于this.props.navigator,这里大家并不曾经在导航链上的各个组件显式地传递navigator属性,而是在Navigator伊始化的时候就在renderScene属性方法里联合布署了,导航链上全部组件的this.props.navigator其实都指向了一个合併的navigator对象,它有四个章程:push和pop,用来向导航链压入和临蓐组件,视觉上就是跻身下一视图和重回上一视图,由此这里当点击顶栏再次来到按键时,直接调用pop方法就再次来到上一视图了。其实也得以把navigator对象传递到TopBarView里,在TopBarView内部调用navigator的pop方法,原理是均等的。而在CharacterView的显明开关事件里,须要保留顾客接受的剧中人物然后跳转到下叁个视图,正是通过props传递的:

this.props.navigator.push({ name:"registerNav", component:RegisterNavView, params:{character:this.state.character} });

1
2
3
4
5
this.props.navigator.push({
      name:"registerNav",
      component:RegisterNavView,
      params:{character:this.state.character}
    });

此处就是调用的navigator属性的push方法向导航链压入新的机件,即进入下一视图。push方法选拔的参数是三个暗含五个天性的靶子,name只是用来标志组件名称,而commponent和params则是标志组件甚至传递给该器件的参数对象,这里的”commponent”和”params”四个key名称是和前面renderScene是应和的,在renderScene回调里边,用到的route.commponent和route.params,正是此处push传递的参数对应的值。
在客户注册视图中,有多个顾客协商须要顾客确认,这里客商左券视图的切换方式与主流程不太相通,而三个Navigator只好在先前时代配置后生可畏种切换格局,由此,这里在Navigator里嵌套了Navigator,效果如下:
图片 3
CharacterView的跳转事件中,向navigator的push传递的机件并不是RegisterView组件,而是传递的RegisterNavView组件,它是被嵌套的三个Navigator,那些子导航链上带有了客户注册视图及客商协商视图。

class RegisterNavView extends Component { constructor(props){ super(props); } handleConfirm(){ //send data to server ··· // this.props.navigator.push({ component:nextView, name:'userInfo' }); } render(){ return ( <View style={styles.container}> <Navigator style={styles.navWrap} initialRoute={{name: 'register', component:RegisterView,params:{navigator:this.props.navigator,onConfirm:this.handleConfirm.bind(this)}}} configureScene={(route) => { return Navigator.SceneConfigs.FloatFromBottom; }} renderScene={(route, navigator) => { let Component = route.component; return <Component {...route.params} innerNavigator={navigator} /> }} /> </View> ); } }

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
class RegisterNavView extends Component {
  constructor(props){
    super(props);
  }
 
  handleConfirm(){
    //send data to server
    ···
    //
    this.props.navigator.push({
        component:nextView,
        name:'userInfo'
      });
  }
 
  render(){
    return (
      <View style={styles.container}>
        <Navigator style={styles.navWrap}
          initialRoute={{name: 'register', component:RegisterView,params:{navigator:this.props.navigator,onConfirm:this.handleConfirm.bind(this)}}}
          configureScene={(route) => {
            return Navigator.SceneConfigs.FloatFromBottom;
          }}
          renderScene={(route, navigator) => {
            let Component = route.component;
            return <Component {...route.params} innerNavigator={navigator} />
          }} />
      </View>
    );
  }
}

其风华正茂被嵌套的导航大家近些日子称为InnerNav,它的初步路由组件正是RegisterView,显示了输入账号密码等音信的视图,它的configureScene设置为“FloatFromBottom”,即从底部浮上来,renderScene也略微区别等,在InnerNav导航链组件上传递的navigator对象名称改成了innerNavigator,以界别主流程Navigator,在RegisterView中有贰个【客户协商】的文字开关,在此个按键上大家调用了向InnerNav压入公约视图的办法:

handleShowUserdoc(){ this.props.innerNavigator.push({ name:"usrdoc", component:RegisterUsrDocView }); }

1
2
3
4
5
6
handleShowUserdoc(){
    this.props.innerNavigator.push({
      name:"usrdoc",
      component:RegisterUsrDocView
    });
  }

而在RegisterUsrDocView即客户协商视图组件中,点击分明开关时大家调用了从InnerNav推出视图的艺术:

handleHideUserdoc(){ this.props.innerNavigator.pop(); }

1
2
3
handleHideUserdoc(){
    this.props.innerNavigator.pop();
}

如此那般内嵌的导航链上的视图就瓜熟蒂落了压入和临盆的完整意义,即使有亟待,还可以够增加更加多组件。
在RegisterNavView组件的handleConfirm方法中,也正是点击注册之后调用的不二等秘书技,那时向服务器发送数据同期须求进入注册的下黄金年代环节了,因而须要主流程的Navigator压入新的视图,所以调用的是this.props.navigator.push,并非innderNavigator的办法。

好了,大致结议和流程就介绍到此处了,绝相比较较简单,实际付出中还是会遇上海重机厂重细节难点,比如整个注册流程中,数据都急需仓库储存在本土,最后统风姿洒脱交由到服务器,如酚酞航链上有比超多组件,那么数量将在拔尖一级以props的主意传送,极度蛋疼,因此才引入了Redux来归总存储和治本,下意气风发篇小说会系统介绍Redux以及在这里个小项目里引入Redux的进度。

打赏扶持自个儿写出更加多好随笔,谢谢!

打赏小编

一、Navigator

打赏扶植作者写出越多好小说,多谢!

任选后生可畏种支付办法

图片 4 图片 5

1 赞 3 收藏 评论

1、简介:大许多时候我们都亟待导航器来应对各异景观(页面卡塔尔间的切换。它通过路由对象来分辨分化的场景,我们那边运用的正是renderScene方法,依照内定的路由来渲染。

关于笔者:D.son

图片 6

80后码农兼伪文青后生可畏枚,闷骚而不木讷,猥琐不流浪荡 个人主页 · 作者的稿子 · 1

图片 7

2、利用Navigator弹出用到的不二秘诀:

(1initialRoute={{ name: 'home', component: HomeScene }} 这一个钦定了私下认可的页面,也正是开发银行的机件页面

(2configureScene={() => {

return Navigator.SceneConfigs.HorizontalSwipeJump;

}}

本条是页面之间跳转时候的动漫片,能够看那几个目录:

node_modules/react-native/Libraries/CustomComponents/Navigator/NavigatorSceneConfigs.js(能够看其它跳转的时候的来头)

(3renderScene:多少个参数中的route包括的事initial的时候传递的name和component,而navigator是一个大家需求用的Navigator的对象,所以当我们获得route中的component的时候,我们就可以将navigator传递给它,正因为如此,大家的组件HomeScene技巧够透过this.props.navigator,获得路由。

(4 假诺要求传参数,则在push的参数后边增添一个参数params,把JSON往死填就好了,这里的params,其实就是在renderScene中return的{...route.params},那样接受的页面只必要通过this.props.id,就可以获得大家传递的参数

(5 OK,那参数怎么回传呢?回调!通过定义三个回调函数,利用this.props 去调用,把参数回传回来

生机勃勃体化代码:

/**

* Sample React Native App

*

*/'use strict';varReact = require('react-native');//增加NavigatorIOSvar{  AppRegistry,  StyleSheet,  Text,  View,  Navigator,  TouchableHighlight,} = React;/*--  运营组件 --*/varMainClass = React.createClass({  render:function() {//component这里安装的是以此组件运转的时候显得的首先个头组件return({              return Navigator.SceneConfigs.HorizontalSwipeJump;          }}          renderScene={(route, navigator) => {            let Component = route.component;            if(route.component) {              return}          }} >);  },});/*--  首页页面组件 --*/var HomeScene = React.createClass({  getInitialState:function () {    return {      id: 'AXIBA001',      flag: null    };  },  render: function() {    return (push me!{this.state.flag && ' I 'm ' + this.state.flag + ', i come from second page'});  },  onPress: function() {    var _me = this;    //大概写成 const navigator = this.props.navigator;    const { navigator } = this.props;    if(navigator)    {        navigator.push({            name: 'touch View',            component: SecondScene,            params: {                id: this.state.id,                getSomething:function(flag) {                  _me.setState({                    flag: flag                  });                }            }        })    }  }});/*--  push后的页面组件 --*/var SecondScene = React.createClass({  render: function() {    return (push sucess!I get {this.props.id},i want back!);  },  onPress: function() {    //或然写成 const navigator = this.props.navigator;    const { navigator } = this.props;    if(this.props.getSomething) {      var flag = 'Axiba002'      this.props.getSomething(flag);    }    if(navigator) {      navigator.pop();    }  }});/*布局样式*/var styles = StyleSheet.create({  container: {    flex: 1,    // justifyContent: 'center',    // alignItems: 'center',    backgroundColor: '#F5FCFF',  },  home: {    paddingTop:74,  },});AppRegistry.registerComponent('AwesonProject', () => MainClass);

增补部分也许会用到的Navigator方法:

getCurrentRoutes() - 获取当前栈里的路由,相当于push进来,未有pop掉的那么些。

jumpBack() - 跳回早前的路由,当然前提是保留今后的,仍然为能够再跳回来,会给您保存原样。

jumpForward() - 上叁个艺术不是调到以前的路由了么,用那几个跳回来就好了。

jumpTo(route) - 跳转到已部分场境而且不卸载。

push(route) - 跳转到新的气象,并且将气象入栈,你能够稍后跳转过去

pop() - 跳转回来还要卸载掉当前情景

replace(route) - 用三个新的路由替换掉当前气象

replaceAtIndex(route, index) - 替换掉内定系列的路由场景

replacePrevious(route) - 替换掉从前的场地

immediatelyResetRouteStack(routeStack) - 用新的路由数组来重新设置路由栈

popToRoute(route) - pop到路由钦定的风貌,别的的风貌将会卸载。

popToTop() - pop到栈中的率先个情景,卸载掉全体的此外场景。

二、NavigatorIOS

1、NavigatorIOS包装了UIKit的导航效率,能够行使左划成效来回到到上风度翩翩分界面。

2、同上含蓄的办法有:

push(route)- 导航器跳转到三个新的路由。

pop()- 回到上意气风发页。

popN(n)- 回到N页之前。当N=1的时候,效果和pop()一样。

replace(route)- 替换当前页的路由,并随时加载新路由的视图。

replacePrevious(route)- 替换上风流罗曼蒂克页的路由/视图。

replacePreviousAndPop(route)- 替换上黄金年代页的路由/视图况兼马上切换回上大器晚成页。

resetTo(route)- 替换最顶尖的路由况兼回到它。

popToRoute(route)- 一贯回到有些钦赐的路由。

popToTop()- 回到最顶层的路由。

代码:

/**

* Sample React Native App

*

*/'use strict';varReact = require('react-native');//增加NavigatorIOSvar{  AppRegistry,  StyleSheet,  Text,  View,  NavigatorIOS,  TouchableHighlight,} = React;/*有那样有些需要?:自定义barBarItem,举个例子自定义名字、图片?*//*--  运维组件 --*/varMainClass = React.createClass({  onRightButtonPress:function(){this.refs.nav.push({      title:'push view',      component: SecondScene,    });  },  render:function() {//component这里设置的是以此组件运转的时候显得的首先个头组件return();  },});/*--  首页页面组件 --*/var HomeScene = React.createClass({  render: function() {    return (push me!);  },  onPress: function() {    this.props.navigator.push({      title: 'touch View',      component: SecondScene,      passProps: { myProp: 'Axiba001' },    });  }});/*--  push后的页面组件 --*/var SecondScene = React.createClass({  render: function() {    return (push sucess!{'hi,this is prams:'+ this.props.myProp});  },});/*布局样式*/var styles = StyleSheet.create({  container: {    flex: 1,    // justifyContent: 'center',    // alignItems: 'center',    backgroundColor: '#F5FCFF',  },  home: {    paddingTop:74,  },});AppRegistry.registerComponent('AwesonProject', () => MainClass);

回调函数基本相仿,不过注意还应该有意气风发部分对导航栏的调节,举个例子:

(1 barTintColorstring

导航条的背景颜色。

(2 initialRoute{component: function, title: string, passProps: object, backButtonIcon: Image.propTypes.source, backButtonTitle: string, leftButtonIcon: Image.propTypes.source, leftButtonTitle: string, onLeftButtonPress: function, rightButtonIcon: Image.propTypes.source, rightButtonTitle: string, onRightButtonPress: function, wrapperStyle: [object Object]}

NavigatorIOS使用"路由"对象来含有要渲染的子视图、它们的性质、以至导航条配置。"push"和其余此外的导航函数的参数都是那样的路由对象。

(3 itemWrapperStyleView#style

导航器中的组件的默许属性。贰个不闻不问的用途是安装富有页面包车型地铁背景颜色。

(4 navigationBarHiddenbool

一个布尔值,决定导航栏是或不是隐伏。

( 5 shadowHiddenbool

叁个布尔值,决定是不是要掩瞒1像素的阴影

( 6 tintColorstring

导航栏上按键的颜料。

( 7 titleTextColorstring

导航器题目标文字颜色。

(8 translucentbool

三个布尔值,决定是不是导航条是半透明的。

相关的链接地址在那间:http://www.tuicool.com/articles/z226zin

编辑:Web前端 本文来源:ReactNative学习执行,使用导航Navigator

关键词: