• 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。
    这里写图片描述

  • 相关阅读:
    菜单代码
    一个三角形证明题
    根号7和根号13的正数部分
    绝对值是大问题,a^2-b^2=2009
    化学
    二次函数错题本:y=ax^2+4ax+3
    大阴线空中加油最厉害!比亚迪等几个分析图
    大阴线空中加油最厉害!比亚迪等几个分析图
    09-使用a标签实现锚链接的两种方法
    08-a超链接标签
  • 原文地址:https://www.cnblogs.com/hehe520/p/6329890.html
Copyright © 2020-2023  润新知