React-Native|Navigator使用&NavigatorBar自定义

前端之家收集整理的这篇文章主要介绍了React-Native|Navigator使用&NavigatorBar自定义前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

最近这段时间再学React-native开发,发现啊,这玩意挺有意思的。于是呢,我想写一系列的博客,再学一遍。或者说跟着大神的思路把代码撸一遍。

强烈推荐去浏览React Native中文网

搭建React-Native开发环境
首先安装node.js,由于对node.js知之甚少。暂且理解安装它的目的是为了,使用它的包管理器npm。
npm可以安装很多开源库上的开源组件,比如可以安装React Native的命令行工具。
安装好命令行工具,就可以使用React-native init Project初始化一个React-native项目。

一个初始化项目安装好后。展开目录,可以看出index.android.js和index.ios.js是分别运行在安卓和苹果设备上的入口。
开发时,为了方便在两种设备上调试,把入口的指向一处。

  1. //import引入相关组件
  2. import React,{ Component } from 'react';
  3. import {
  4. Text,View
  5. } from 'react-native';
  6.  
  7. export default class Start extends Component{
  8. /* 在React-native里,使用最多的是弹性盒子模型。其默认的方向是column。 也就是默认的主轴是纵向的。 */
  9. render(){
  10. return(<View style={{flex:1,justifyContent:'center',backgroundColor:'red'}}>
  11. <Text>启动页面</Text>
  12. </View>)
  13. }
  14. }

在index.android.js和index.ios.js中,导入该组件,并注册该组件

  1. import Start from './js/Start' ..... //注册根组件,因为项目名叫startByRN,所以这里第一个参数默认也是startByRN 随意的修改为其他,总是提示项目startByRN未被注册。 我姑且把它理解为App的名字,运行在安卓模拟器上应用名也是startByRN。 AppRegistry.registerComponent('startByRN',() => Start);

首先完成几个页面之间的跳转和数据传递,那就必须要先了解Navigator
在React-Naive中文网上,只有NavigatorIOS组件相关的介绍,如果要在两个平台都能使用,则需要使用Navigator。
可是在React-Naive0.44版本后,Navigator好像换了包了。

  1. 如果要使用,使用npm安装:
  2. npm i react-native-deprecated-custom-components --save
  3.  
  4. 引入Navigator(Navigator不是默认导出(export default)的组件,需要用大括号括起来)
  5. import {Navigator} from 'react-native-deprecated-custom-components';
  6.  
  7. 安装完成之后,在项目package.jsondependencies依赖中会有声明,如果没有表示没有安装成功。
  1. 如果要查看React-Naive版本,进入到项目目录,执行react-natice -v
  2. 引入组件完成后,需要重新react-native run-android安装。
  3. 只是单纯的重新加载js,会提示找不到引入的组件。

Navigator的一个简单的例子

在组件Start中定义Navigator的规则

  1. render(){
  2. return (
  3. <Navigator
  4. //初始化路由,指定FirstJump为首次渲染的组件
  5. initialRoute={
  6. {
  7. component:FirstJump,}
  8. }
  9.  
  10. //组件渲染时触发,有动态组件的渲染和静态组件的渲染
  11. //以下是动态渲染组件,定义了组件的两个属性navigator和一个传递其他参数的对象。
  12. //'...'会把该对象展开。所以在访问该对象的参数时,不用加上前缀(对象名字)(该对象名字随意取)
  13. renderScene={
  14. (route,navigator)=>{
  15. let Component=route.component;
  16. return <Component
  17. navigator={navigator}
  18. {...route.params}
  19. />
  20. }
  21. }
  22.  
  23. //定义渲染动画
  24. configureScene={
  25. (route,routeStack)=>{
  26. if(route.type='Bottom'){
  27. return Navigator.SceneConfigs.FloatFromBottom
  28. }else if(route.type='Right'){
  29. return Navigator.SceneConfigs.FloatFromRight
  30. }else{
  31. return Navigator.SceneConfigs.FloatFromRight
  32. }
  33. }
  34. }
  35. />
  36. )
  37. }

FirstJump:

  1. constructor(props) { super(props); this.word='' } jump(){ this.props.navigator.push({ component:SecondJump,params:{ message:'come by FirstJump',onCallBack:word=>this.word=word },type:'Bottom' }); } render() { return ( <View style={{flex:1}}> <View style={{flexDirection:'row',justifyContent:'center',padding:10}}> <Text style={{ color:'#31353a'}}>FirstJump</Text> </View> <TouchableHighlight activeOpacity={0.5} underlayColor='#ff8400' style={{ padding:10,flexDirection:'row',backgroundColor:'#ff9e21'}} onPress={()=>this.jump()}> <Text style={{color:'white'}}>跳转SecondJump</Text> </TouchableHighlight> <View style={{flexDirection:'row',padding:10}}> <Text style={{ color:'#31353a'}}>SecondJump传递过来的值为:{this.word}</Text> </View> </View> ) }

SecondJump:

  1. constructor(props) { super(props); } onBack(){ this.props.navigator.pop(); //回调onCallBack,利用回调函数传递值 this.props.onCallBack('come by SecondJump') } render() { return ( <View style={{flex:1}}> <View style={{flexDirection:'row',padding:10}}> <Text style={{ color:'#31353a'}}>SecondJump</Text> </View> <TouchableHighlight activeOpacity={0.5} underlayColor='#ff8400' style={{ padding:10,backgroundColor:'#ff9e21'}} onPress={()=>this.onBack()}> <Text style={{color:'white'}}>返回至FirstJump</Text> </TouchableHighlight> <View style={{flexDirection:'row',padding:10}}> <Text style={{ color:'#31353a'}}>FirstJump传递过来的值为:{this.props.message}</Text> </View> </View> ) }

FirstJump跳转到SecondJump,再返回。效果如下:

自定义导航头

以前在android中,总会写一个导航头,一般左边是返回按钮,中间是title,最右也是一个按钮。
写完该布局,在其他布局中include进去。
下面同样的写一个自定义的导航头。

  1. //设置android和iOS设备上不同的NavigatorBar高度
  2. const NavigatorBar_ANDROID_HEIGHT=50;
  3. const NavigatorBar_IOS_HEIGHT=44;
  4.  
  5. export default class NavigatorBar extends Component{
  6. /* 自定义导航栏: 一般的导航栏左边是返回按钮,中间是title,右边也有一个按钮。 */
  7. constructor(props){
  8. super(props);
  9. }
  10.  
  11. //设置属性的规则
  12. static propTypes={
  13. //定义属性title为string且该属性是必须的。如果不传递该属性,不会报错,但是会有警告。提示value undifined
  14. title:PropTypes.string.isrequired,//左右两边传递进来的要是组件
  15. leftButton:PropTypes.element,rightButton:PropTypes.element,}
  16.  
  17. render(){
  18. //状态栏
  19. let statusBar=
  20. <StatusBar hidden={false} animated={true} {...this.props.statusBar}/>;
  21. return(
  22. <View>
  23. {statusBar}
  24. <View style={styles.navgigatorBar}>
  25. {this.props.leftButton}
  26. <View style={styles.title}>
  27. <Text style={styles.titleText}>{this.props.title}</Text>
  28. </View>
  29. {this.props.rightButton}
  30. </View>
  31. </View>
  32. )
  33. }
  34. }
  35.  
  36. const styles=StyleSheet.create({
  37.  
  38. navgigatorBar:{
  39. height:Platform.OS==='ios'?NavigatorBar_IOS_HEIGHT:NavigatorBar_ANDROID_HEIGHT,flexDirection:'row',justifyContent:'space-between',alignItems:'center',backgroundColor:'#fff',padding:10,},//当Navigator左右两边都没有相关组件传递进来,也要保证title居中
  40. //相对定位,左右两边距离相等,保持居中。单独设置justifyContent:'center'无法水平居中
  41. title:{
  42. flexDirection:'row',position:'absolute',left:10,right:10,titleText:{
  43. fontSize:18,color:'#31353a',});

在其他控件中使用该导航头:

  1. export default class ManualNavigatorPage extends Component{
  2. constructor(props){
  3. super(props);
  4. }
  5.  
  6. onBack(){
  7.  
  8. }
  9.  
  10. render(){
  11. return(
  12. <NavigatorBar
  13. statusBar={{backgroundColor:'#2196f3'}}
  14. leftButton={
  15. //TouchableOpacity按下会改变视图的不透明度,来表达按钮被点击。
  16. //可以设置activeOpacity。
  17. (<TouchableOpacity
  18. onPress={
  19. ()=>this.onBack()
  20. }>
  21. {/*tintColor可以为图表着色*/}
  22. <Image
  23. style={{width:50,height:50,tintColor:'red'}}
  24. source={require('../images/back_d_nor.png')}/>
  25. </TouchableOpacity>)
  26. }
  27.  
  28. title={'测试'}
  29.  
  30. rightButton={
  31. (<TouchableOpacity>
  32. <Text style={styles.titleText}>保存</Text>
  33. </TouchableOpacity>)
  34. }
  35. />
  36. )
  37. }
  38. }
  39.  
  40. const styles=StyleSheet.create({
  41. titleText:{
  42. fontSize:16,});

最后如下:

猜你在找的React相关文章