ReactNative学习实践【lom599乐百家手机】,使用导航Navigator

 百家乐-前端     |      2019-11-24 20:45

ReactNative学习执行:Navigator履行

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

本文作者: 伯乐在线 - D.son 。未经作者许可,幸免转发!
迎接出席伯乐在线 专栏撰稿者。

离上次写EvoqueN笔记有生机勃勃段时间了,期间参加了三个新类型,只在近年的空余时间继续学习推行,因而进程正如缓慢,可是那并不代表未有新进展,其实那些小东西离上次发布文书时曾经有了生龙活虎对一大的变迁了,当中国电影响最大的转移就是引进了Redux,前边会系统介绍一下。
在开端主旨之前,先增补有个别上回聊到的卡通片初探(像本人如此可靠严厉的程序猿,必须更上风华正茂层楼,┗|`O′|┛ 嗷~~)。

上回文说起,经过我们本人定义了余弦动画函数之后,动态设定state的4个参数,完成了相比流利的加载动漫,这里恐怕有对象曾经注意到了,我们非常频仍的调用了setState方法,这在React和奥德赛N中都未来生可畏对风流倜傥禁忌的,每贰遍setState都会触发render方法,也就代表更频仍的假造DOM比较,特别是在途睿欧N中,那还表示更频繁的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));
  }

成效如下:
lom599乐百家手机 1
那边有意在登记央求完成之后并未有隐蔽loading动漫,因而同有的时候候举行了视图切换和loading七个卡通,效果能够选拔~

好了,该走入前日的宗旨了。先全体看一下那少年老付加物级贯彻的功力(哒哒哒~):
lom599乐百家手机 2

最首借使盲目跟风了一个新客户注册流程,完结起来也并不复杂,全体布局是用一个TiggoN组件Navigator来做导航,就算有另三个NavigatorIOS组件在iOS系统上表现尤为精粹,不过思虑到揽胜N自身希望能够同期在安卓和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,效果如下:
lom599乐百家手机 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

打赏补助自个儿写出更加多好小说,感激!

任选朝气蓬勃种支付办法

lom599乐百家手机 4 lom599乐百家手机 5

1 赞 3 收藏 评论

1、简要介绍:大多数时候我们都亟需导航器来回应差别场景(页面卡塔尔间的切换。它通过路由对象来鉴定识别不一样之处,大家这里运用的便是renderScene方法,依照钦赐的路由来渲染。

至于作者:D.son

lom599乐百家手机 6

80后码农兼伪文青大器晚成枚,闷骚而不木讷,猥琐不流浪荡 个人主页 · 小编的文章 · 1

lom599乐百家手机 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、同上含蓄的主意有:

上一篇:十行HTML实现增强现实 下一篇:没有了