React Native自定义导航栏

简介: 之前我们学习了可触摸组件和页面导航的使用的使用: 从零学React Native之09可触摸组件 … 从零学React Native之03页面导航 …经过之前的学习, 我们可以完成一个自定义导航栏了, 效果如下: 我们需要创建一个 NaviBar.js 用来显示顶部的导航栏, 还需要四个界面(Page1.js,Page2.js,Page3.js,Page4.js

之前我们学习了可触摸组件和页面导航的使用的使用:
从零学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: {
        width: 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。
这里写图片描述

相关文章
|
1月前
|
人工智能 自然语言处理 前端开发
SpringBoot + 通义千问 + 自定义React组件:支持EventStream数据解析的技术实践
【10月更文挑战第7天】在现代Web开发中,集成多种技术栈以实现复杂的功能需求已成为常态。本文将详细介绍如何使用SpringBoot作为后端框架,结合阿里巴巴的通义千问(一个强大的自然语言处理服务),并通过自定义React组件来支持服务器发送事件(SSE, Server-Sent Events)的EventStream数据解析。这一组合不仅能够实现高效的实时通信,还能利用AI技术提升用户体验。
161 2
|
3月前
|
设计模式 存储 前端开发
React开发设计模式及原则概念问题之自定义Hooks的作用是什么,自定义Hooks设计时要遵循什么原则呢
React开发设计模式及原则概念问题之自定义Hooks的作用是什么,自定义Hooks设计时要遵循什么原则呢
|
2月前
|
前端开发
React给antd中TreeSelect组件左侧加自定义图标icon
本文介绍了如何在React中为Ant Design的TreeSelect组件的每个树节点添加自定义图标,并解决了因缺少key属性而导致的警告问题,展示了如何通过递归函数处理treeData数据并为每个节点添加图标。
105 2
React给antd中TreeSelect组件左侧加自定义图标icon
|
2月前
|
前端开发 Python
React技术栈-React路由插件之自定义组件标签
关于React技术栈中React路由插件自定义组件标签的教程。
52 4
React技术栈-React路由插件之自定义组件标签
|
1月前
|
前端开发 JavaScript API
自定义React Hooks综合指南
本文介绍了React Hooks及其在组件开发中的作用,重点讲解了自定义Hook的创建和使用方法。通过实例展示了如何创建`useWindowWidth`、`useFetch`和`useForm`等自定义Hook,并分享了使用自定义Hook的最佳实践。文章强调了自定义Hook在提高代码复用性和组件可维护性方面的重要性。
49 0
|
6月前
|
开发框架 Dart 前端开发
【Flutter前端技术开发专栏】Flutter与React Native的对比与选择
【4月更文挑战第30天】对比 Flutter(Dart,强类型,Google支持,快速热重载,高性能渲染)与 React Native(JavaScript,庞大生态,热重载,依赖原生渲染),文章讨论了开发语言、生态系统、性能、开发体验、学习曲线、社区支持及项目选择因素。两者各有优势,选择取决于项目需求、团队技能和长期维护考虑。参考文献包括官方文档和性能比较文章。
238 0
【Flutter前端技术开发专栏】Flutter与React Native的对比与选择
|
3月前
|
前端开发 JavaScript
|
4月前
|
前端开发 JavaScript Android开发
React Native跨平台开发实战
【7月更文挑战第21天】React Native为跨平台移动应用开发提供了一种高效且强大的解决方案。通过本文的学习,你应该能够掌握React Native的基本概念和实战步骤,并开始在你的项目中使用React Native进行开发。随着你对React Native的深入理解,你将能够利用其强大的功能来构建更加复杂和高效的移动应用。
|
4月前
|
前端开发 JavaScript 数据格式
react18【系列实用教程】Hooks (useState,useReducer,useRef,useEffect,useContext,useMemo,useCallback,自定义 Hook )
react18【系列实用教程】Hooks (useState,useReducer,useRef,useEffect,useContext,useMemo,useCallback,自定义 Hook )
90 1
|
5月前
|
前端开发 自动驾驶 程序员
鸿蒙? 车载?Flutter? React Native? 为什么我劝你三思,说点不一样的
本文探讨了在信息技术快速发展的背景下,开发者如何选择学习路径。作者提倡使用终局思维来规划职业发展,考虑技术的长远影响。终局思维注重长远目标、系统分析、反向规划和动态调整。以车载开发为例,预测未来智能汽车可能由语音助手主导,而非依赖平板界面。此外,作者建议不要过分投入打工状态,应思考创建自己的产品,如App,以实现技能补充和额外收入。选择对未来发展和自主性有益的技术,如Kotlin,比盲目追求热点更为重要。做减法和有标准的选择,能帮助减轻焦虑,实现更高效的成长。关注公众号“AntDream”获取更多相关内容。
129 1