zoukankan      html  css  js  c++  java
  • React Native自定义导航栏

    之前我们学习了可触摸组件和页面导航的使用的使用:
    从零学React Native之09可触摸组件

    从零学React Native之03页面导航

    经过之前的学习, 我们可以完成一个自定义导航栏了, 效果如下:
    这里写图片描述

    我们需要创建一个 NaviBar.js 用来显示顶部的导航栏, 还需要四个界面(Page1.js,Page2.js,Page3.js,Page4.js)。 当然还需要修改index.android.js或者index.ios.js 用来处理4个界面的切换。

    导航栏NaviBar 实现

    这里, 我们就假设应用有4个栏目, 每个按钮的宽高比为 4:3
    直接贴代码了:

    import React, { Component } from 'react';
    import {
        AppRegistry,
        StyleSheet,
        View,
        Text,
        TouchableHighlight,
    } from 'react-native';
    
    var Dimensions = require("Dimensions");
    var totalWidth = Dimensions.get('window').width;// 屏幕宽度
    let naviButtonWidth = totalWidth / 4;    //计算导航条每个宽度
    let naviButtonHeight = naviButtonWidth * 0.75;   // 导航条每个高度
    export  default class NaviBar extends Component {
        // 构造
        constructor(props) {
            super(props);
            this._tab0Pressed = this._tab0Pressed.bind(this);
            this._tab1Pressed = this._tab1Pressed.bind(this);
            this._tab2Pressed = this._tab2Pressed.bind(this);
            this._tab3Pressed = this._tab3Pressed.bind(this);
        }
    
        //四个按钮 被按下时处理函数
        _tab0Pressed() {
            this.props.onNaviBarPress(0);
        }
    
        _tab1Pressed() {
            this.props.onNaviBarPress(1);
        }
    
        _tab2Pressed() {
            this.props.onNaviBarPress(2);
        }
    
        _tab3Pressed() {
            this.props.onNaviBarPress(3);
        }
    
        render() {
            //通过属性得知哪个导航按钮是当前导航页, 这个导航用灰色背景
            //利用JavaScript数组的map函数,从一个数组对应生成另一个数组buttonColors
            // 看不懂该函数的,看下面的解释
            var buttonColors = this.props.naviBarStatus.map(function (aNumber) {
                if (aNumber == 0) return 'white';
                return 'gray';
            });
            return (
                //根View
                <View style={styles.naviRow}>
                    <TouchableHighlight onPress={this._tab0Pressed}>
                        <View style={[styles.button,{backgroundColor:buttonColors[0]}]}>
                            <Text style={styles.textStyle1}>
                                条目一
                            </Text>
                        </View>
                    </TouchableHighlight>
                    <TouchableHighlight onPress={this._tab1Pressed}>
                        <View style={[styles.button,{backgroundColor:buttonColors[1]}]}>
                            <Text style={styles.textStyle1}>
                                条目二
                            </Text>
                        </View>
                    </TouchableHighlight>
                    <TouchableHighlight onPress={this._tab2Pressed}>
                        <View style={[styles.button,{backgroundColor:buttonColors[2]}]}>
                            <Text style={styles.textStyle1}>
                                条目三
                            </Text>
                        </View>
                    </TouchableHighlight>
                    <TouchableHighlight onPress={this._tab3Pressed}>
                        <View style={[styles.button,{backgroundColor:buttonColors[3]}]}>
                            <Text style={styles.textStyle1}>
                                条目四
                            </Text>
                        </View>
                    </TouchableHighlight>
                </View>
            );
        }
    }
    // 声明属性, 方便使用当前组件
    NaviBar.propTypes = {
        naviBarStatus: React.PropTypes.arrayOf(React.PropTypes.number).isRequired,
        onNaviBarPress: React.PropTypes.func.isRequired
    };
    
    //样式 
    const styles = StyleSheet.create({
        naviRow: {
            flexDirection: 'row'
        },
        button: {
             naviButtonWidth,
            height: naviButtonHeight,
            justifyContent: 'center'
        },
        textStyle1: {
            fontSize: 20,
            textAlign: 'center'
        }
    });

    上面用到了, Map函数 ,
    Map函数的作用是按照某种关系从原数组”映射”出新数组. 如下面求平方的例子:

    var data= [1,2,3,4];
    var newArray=data.map((item)=>{return item*item});
    console.log(newArray);  //输出[1,4,9,16]

    统一处理四个界面的切换

    我们需要在index.android.js 或者index.ios.js 这个代码比较简单, 只需要导入四个界面, 用Navigator组件切换就可以了。

    import React, { Component } from 'react';
    import {
        AppRegistry,
        StyleSheet,
        Navigator
    } from 'react-native';
    
    import Page1 from './Page1';
    import Page2 from './Page2';
    import Page3 from './Page3';
    import Page4 from './Page4';
    class AwesomeProject extends Component {
        //告知Navigator 模块切换时的效果
        configureScene() {
            return Navigator.SceneConfigs.FadeAndroid;
        }
        //根据传递的信息, 处理界面的切换
        renderScene(router, navigator) {
            this._navigator = navigator;
            switch (router.name) {
                case 'Page1':
                    return <Page1 navigator={navigator}/>;
                case 'Page2':
                    return <Page2 navigator={navigator}/>;
                case 'Page3':
                    return <Page3 navigator={navigator}/>;
                case 'Page4':
                    return <Page4 navigator={navigator}/>;
            }
        }
        render() {
            return (
                //根View
                <Navigator
                    initialRoute={{name:'Page1'}}
                    configureScene={this.configureScene}
                    renderScene={this.renderScene}/>
            );
        }
    }
    AppRegistry.registerComponent('AwesomeProject', () => AwesomeProject);

    界面

    上面的代码需要引入Page1 - Page4, 这个四个界面非常相似, 我们只贴其中一个了.
    Page1.js

    import React, { Component } from 'react';
    import {
        View,
        StyleSheet,
    } from 'react-native';
    import NaviBar from './NaviBar';
    
    export  default class Page1 extends Component {
        // 构造
        constructor(props) {
            super(props);
            // 初始状态
            this.onNaviBarPress = this.onNaviBarPress.bind(this);
        }
    
        render() {
            // 不同的Page,需要修改下面的这个数组, 通过数组控制导航栏条目显示状态
            var naviStatus = [1, 0, 0, 0];
            return (
                <View style={styles.container}>
                    <NaviBar naviBarStatus={naviStatus}
                             onNaviBarPress={this.onNaviBarPress}/>
                    <View style={styles.whatLeft}/>
                </View>
            );
        }
        //不同的page需要修改返回值
        onNaviBarPress(aNumber) {
            switch (aNumber) {
                case 0:
                    return;
                case 1:
                    //通过replace切换
                    this.props.navigator.replace({
                        name: 'Page2'
                    });
                    return;
                case 2:
                    this.props.navigator.replace({
                        name: 'Page3'
                    });
                    return;
                case 3:
                    this.props.navigator.replace({
                        name: 'Page4'
                    });
                    return;
            }
        }
    }
    const styles = StyleSheet.create({
        container: {
            flex: 1
        },
        whatLeft: {  // 组件定义了一个上边框
            flex: 1,
            borderTopWidth: 1,
            borderColor: 'black',
            backgroundColor:'red' //每个界面背景颜色不一样
        }
    });

    顺便指出两点: 当根View没有指定背景色时, 默认值是一种灰色; 当子View没有指定背景色时,会继承父View的背景色。

    更多精彩请关注微信公众账号likeDev,公众账号名称:爱上Android。
    这里写图片描述

  • 相关阅读:
    【转载】SAP_ECC6.0_EHP4或SAP_ECC6.0_EHP5_基于Windows_Server_2008R2_和SQL_server_2008下的安装
    使用delphi 开发多层应用(二十四)KbmMW 的消息方式和创建WIB节点
    使用delphi 开发多层应用(二十三)KbmMW 的WIB
    实现KbmMw web server 支持https
    KbmMW 服务器架构简介
    Devexpress VCL Build v2014 vol 14.1.1 beta发布
    使用delphi 开发多层应用(二十二)使用kbmMW 的认证管理器
    KbmMW 4.50.00 测试版发布
    Basic4android v3.80 beta 发布
    KbmMW 认证管理器说明(转载)
  • 原文地址:https://www.cnblogs.com/hehe520/p/6329890.html
Copyright © 2011-2022 走看看