美文网首页
Navigator的简单使用&自定义NavigatorB

Navigator的简单使用&自定义NavigatorB

作者: real阿苏勒 | 来源:发表于2017-07-10 18:39 被阅读156次

最近这段时间再学Raect-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是分别运行在安卓和苹果设备上的入口。
开发时,为了方便在两种设备上调试,把入口的指向一处。

//import引入相关组件
import React, { Component } from 'react';
import {
    Text,
    View
} from 'react-native';

export default class Start extends Component{
    /*
        在React-native里,使用最多的是弹性盒子模型。其默认的方向是column。
        也就是默认的主轴是纵向的。
    */
    render(){
        return(<View style={{flex:1,
            justifyContent:'center',
            backgroundColor:'red'}}>
            <Text>启动页面</Text>
        </View>)
    }
}

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

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

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

如果要使用,使用npm安装:
npm i react-native-deprecated-custom-components --save

引入Navigator(Navigator不是默认导出(export default)的组件,需要用大括号括起来)
import {Navigator} from 'react-native-deprecated-custom-components';

安装完成之后,在项目package.json的dependencies依赖中会有声明,如果没有表示没有安装成功。
如果要查看React-Naive版本,进入到项目目录,执行react-natice -v
引入组件完成后,需要重新react-native run-android安装。
只是单纯的重新加载js,会提示找不到引入的组件。

Navigator的一个简单的例子

在组件Start中定义Navigator的规则

render(){
            return (
                <Navigator
                    //初始化路由,指定FirstJump为首次渲染的组件
                    initialRoute={
                        {
                            component:FirstJump,
                        }
                    }

//组件渲染时触发,有动态组件的渲染和静态组件的渲染
//以下是动态渲染组件,
//定义了组件的两个属性navigator和一个传递其他参数的对象。
 //'...'会把该对象展开。
//所以在访问该对象的参数时,不用加上前缀(对象名字)(该对象名字随意取)
                    renderScene={
                        (route,navigator)=>{
                            let Component=route.component;
                            return <Component
                                navigator={navigator}
                                {...route.params}
                            />
                        }
                    }

                    //定义渲染动画
                    configureScene={
                        (route,routeStack)=>{
                            if(route.type='Bottom'){
                                return Navigator.SceneConfigs.FloatFromBottom
                            }else if(route.type='Right'){
                                return Navigator.SceneConfigs.FloatFromRight
                            }else{
                                return Navigator.SceneConfigs.FloatFromRight
                            }
                        }
                    }
                />
            )
    }

FirstJump:

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',
                        justifyContent:'center',
                        backgroundColor:'#ff9e21'}}
                    onPress={()=>this.jump()}>
                        <Text style={{color:'white'}}>跳转到SecondJump</Text>
                </TouchableHighlight>

                <View style={{flexDirection:'row',justifyContent:'center',padding:10}}>
                    <Text style={{
                        color:'#31353a'}}>SecondJump传递过来的值为:{this.word}</Text>
                </View>
            </View>
        )
    }

SecondJump:

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',justifyContent:'center',padding:10}}>
                    <Text style={{
                        color:'#31353a'}}>SecondJump</Text>
                </View>

                <TouchableHighlight
                    activeOpacity={0.5}
                    underlayColor='#ff8400'
                    style={{
                        padding:10,
                        flexDirection:'row',
                        justifyContent:'center',
                        backgroundColor:'#ff9e21'}}
                    onPress={()=>this.onBack()}>
                    <Text style={{color:'white'}}>返回至FirstJump</Text>
                </TouchableHighlight>
                <View style={{flexDirection:'row',justifyContent:'center',padding:10}}>
                    <Text style={{
                        color:'#31353a'}}>FirstJump传递过来的值为:{this.props.message}
</Text>
                </View>
            </View>
        )
    }

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

自定义导航头

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

//设置android和iOS设备上不同的NavigatorBar高度
const NavigatorBar_ANDROID_HEIGHT=50;
const NavigatorBar_IOS_HEIGHT=44;

export default class NavigatorBar extends Component{
    /*
        自定义导航栏:
        一般的导航栏左边是返回按钮,中间是title,右边也有一个按钮。
    */
    constructor(props){
        super(props);
    }

    //设置属性的规则
   static propTypes={
 //定义属性title为string且该属性是必须的。
//如果不传递该属性,不会报错,但是会有警告。提示value undifined
       title:PropTypes.string.isRequired,
       //左右两边传递进来的要是组件
       leftButton:PropTypes.element,
       rightButton:PropTypes.element,
   }

   render(){
        //状态栏
       let statusBar=
               <StatusBar hidden={false} animated={true} {...this.props.statusBar}/>;
        return(
            <View>
                {statusBar}
                <View style={styles.navgigatorBar}>
                    {this.props.leftButton}
                    <View style={styles.title}>
                        <Text style={styles.titleText}>{this.props.title}</Text>
                    </View>
                    {this.props.rightButton}
                </View>
            </View>
        )
    }
}

const  styles=StyleSheet.create({

    navgigatorBar:{
        height:Platform.OS==='ios'?NavigatorBar_IOS_HEIGHT:NavigatorBar_ANDROID_HEIGHT,
        flexDirection:'row',
        justifyContent:'space-between',
        alignItems:'center',
        backgroundColor:'#fff',
        padding:10,
    },

    //当Navigator左右两边都没有相关组件传递进来,也要保证title居中
    //相对定位,左右两边距离相等,保持居中。单独设置justifyContent:'center'无法水平居中
    title:{
      flexDirection:'row',
      alignItems:'center',
      justifyContent:'center',
      position:'absolute',
      left:10,
      right:10,
    },

    titleText:{
        fontSize:18,
        color:'#31353a',
    },
});

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

export default class ManualNavigatorPage extends Component{
    constructor(props){
        super(props);
    }

    onBack(){

    }

    render(){
        return(
                <NavigatorBar
                     statusBar={{backgroundColor:'#2196f3'}}
                     leftButton={
                         //TouchableOpacity按下会改变视图的不透明度,来表达按钮被点击。
                         //可以设置activeOpacity。
                            (<TouchableOpacity
                                    onPress={
                                        ()=>this.onBack()
                                    }>
                                    {/*tintColor可以为图表着色*/}
                                    <Image
                                        style={{width:50,height:50,tintColor:'red'}}
                                        source={require('../images/back_d_nor.png')}/>
                                </TouchableOpacity>)
                    }

                    title={'测试'}

                    rightButton={
                        (<TouchableOpacity>
                                <Text style={styles.titleText}>保存</Text>
                            </TouchableOpacity>)
                    }
                />
        )
    }
}

const styles=StyleSheet.create({
    titleText:{
        fontSize:16,
        color:'#31353a',
    },
});

最后如下:

自定义Navigator

相关文章

网友评论

      本文标题:Navigator的简单使用&自定义NavigatorB

      本文链接:https://www.haomeiwen.com/subject/bafchxtx.html