当前位置:首页 > 芯闻号 > 充电吧
[导读]先来看下效果:这里需要用到两个第三方插件:react-native-router-flux 路由,https://github.com/aksonov/react-native-router-flux

先来看下效果:


这里需要用到两个第三方插件:

react-native-router-flux 路由,https://github.com/aksonov/react-native-router-flux

react-native-scrollable-tab-view 选项卡,https://github.com/skv-headless/react-native-scrollable-tab-view

prop-types 类型检测库

阅读官方文档,安装这三个插件

$ npm install react-native-router-flux --save
$ npm install react-native-scrollable-tab-view --save
$ npm install prop-types --save

在App.js中引入插件

import { Router, Scene } from 'react-native-router-flux';
import ScrollableTabView from 'react-native-scrollable-tab-view';

在工作目录下创建components文件夹,并添加customTabBar.js文件作为tab栏,如下

import React, {Component} from 'react';
import {
    Platform,
    StyleSheet,
    StatusBar,
    View,
    TouchableOpacity,
    Image,
    Text,
} from 'react-native';
//第三方插件
import PropTypes from 'prop-types';
//自定义组件
import Common from './common'; //公共类

const tabIcons = [
    require('../resources/images/tabs/home_v.png'),
    require('../resources/images/tabs/home_x.png'),
    require('../resources/images/tabs/headset_v.png'),
    require('../resources/images/tabs/headset_x.png'),
    require('../resources/images/tabs/bought_v.png'),
    require('../resources/images/tabs/bought_x.png'),
    require('../resources/images/tabs/mine_v.png'),
    require('../resources/images/tabs/mine_x.png')
];

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

    static setAnimationValue({value}) {
        console.log(value);
    }

    componentDidMount() {
        // Animated.Value监听范围 [0, tab数量-1]
        this.props.scrollValue.addListener(CustomTabBar.setAnimationValue);
    }

    renderTabOption(tab, i) {
        let color = this.props.activeTab === i ? "#1296db" : "#707070"; // 判断i是否是当前选中的tab,设置不同的颜色
        let tabName = this.props.tabNames[i];
        return (this.props.goToPage(i)} style={[styles.tab]} key={'tab' + i}>{tabName});
    }

    renderTabs() {
        if (true !== this.props.placeMiddle || 0 !== this.props.tabs.length%2) {
            return this.props.tabs.map((tab, i) => this.renderTabOption(tab, i));
        } else  {
            let tabs = [];
            for (let i = 0; i < this.props.tabs.length; i++) {
                let tab = this.props.tabs[i];
                if (i === parseInt(this.props.tabs.length/2)) {
                    let middle = ();
                    tabs.push(middle);
                }
                tabs.push(this.renderTabOption(tab, i));
            }
            return tabs;
        }
    }

    render() {
        let tabBarHeight = Platform.select({
            ios: Common.isIphoneX ? 68 : 49,
            android: 49,
        });
        return ({this.renderTabs()});
    }
}

CustomTabBar.propTypes = {
    goToPage: PropTypes.func, // 跳转到对应tab的方法
    activeTab: PropTypes.number, // 当前被选中的tab下标
    tabs: PropTypes.array, // 所有tabs集合
    tabNames: PropTypes.array, // 保存Tab名称
    tabIconNames: PropTypes.array, // 保存Tab图标
};

const styles = StyleSheet.create({
    tabs: {
        flexDirection: 'row',
        backgroundColor:'#ffffff',
        borderTopWidth: 0.5,
        borderTopColor: '#cdcdcd',
    },
    tab: {
        flex: 1,
        flexDirection: 'column',
        justifyContent: 'center',
        alignItems: 'center',
    },
    tabBox: {
        flexDirection: 'column',
        justifyContent: 'center',
        alignItems: 'center',
        width: 48,
        height: 48,
    },
    tabMiddleBox: {
        flex: 1,
        flexDirection: 'column',
        justifyContent: 'center',
        alignItems: 'center',
        width: 48,
        height: 48,
    },
    tabBoxIcon: {
        width: 22,
        height: 22,
    },
    tabBoxName: {
        fontSize: 10,
        marginTop: 3,
    },
});

这里用到了一个公共类common.js

import {
    Dimensions,
    PixelRatio,
    Platform
} from 'react-native';


export let screenWidth = Dimensions.get('window').width;
export let screenHeight = Dimensions.get('window').height;
export let fontScale = PixelRatio.getFontScale();
export let pixelRatio = PixelRatio.get();


//像素密度
export const DEFAULT_DENSITY = 2;
//px转换成dp
//以iphone6为基准,如果以其他尺寸为基准的话,请修改下面的750和1334为对应尺寸即可.
const width2x = 750 / DEFAULT_DENSITY;
//px转换成dp
const height2x = 1334 / DEFAULT_DENSITY;
// iPhoneX
const X_WIDTH = 375;
const X_HEIGHT = 812;


/**
 * 设置字体的size(单位px)
 * @param size 传入设计稿上的px
 * @returns {Number} 返回实际sp
 */
export function autoFontSize(size) {
    let scaleWidth = screenWidth / width2x;
    let scaleHeight = screenHeight / height2x;
    let scale = Math.min(scaleWidth, scaleHeight);
    size = Math.round((size * scale + 0.5));
    return size / DEFAULT_DENSITY;
}


/**
 * 屏幕适配,缩放size
 * @param size
 * @returns {Number}
 */
export function autoScaleSize(size) {
    let scaleWidth = screenWidth / width2x;
    let scaleHeight = screenHeight / height2x;
    let scale = Math.min(scaleWidth, scaleHeight);
    size = Math.round((size * scale + 0.5));
    return size / DEFAULT_DENSITY;
}


/**
 * 判断是否为iphoneX
 * @returns {boolean}
 */
export function isIphoneX() {
    return (
        Platform.OS === 'ios' &&
        ((screenHeight === X_HEIGHT && screenWidth === X_WIDTH) ||
        (screenHeight === X_WIDTH && screenWidth === X_HEIGHT))
    )
}


Date.prototype.format=function(fmt) {
    let o = {
        "M+" : this.getMonth()+1, //月份
        "d+" : this.getDate(), //日
        "h+" : this.getHours()%12 === 0 ? 12 : this.getHours()%12, //小时
        "H+" : this.getHours(), //小时
        "m+" : this.getMinutes(), //分
        "s+" : this.getSeconds(), //秒
        "q+" : Math.floor((this.getMonth()+3)/3), //季度
        "S" : this.getMilliseconds() //毫秒
    };
    let weekday = {
        "0" : "/u65e5",
        "1" : "/u4e00",
        "2" : "/u4e8c",
        "3" : "/u4e09",
        "4" : "/u56db",
        "5" : "/u4e94",
        "6" : "/u516d"
    };
    if(/(y+)/.test(fmt)){
        fmt=fmt.replace(RegExp.$1, (this.getFullYear()+"").substr(4 - RegExp.$1.length));
    }
    if(/(E+)/.test(fmt)){
        fmt=fmt.replace(RegExp.$1, ((RegExp.$1.length>1) ? (RegExp.$1.length>2 ? "/u661f/u671f" : "/u5468") : "")+weekday[this.getDay()+""]);
    }
    for(let k in o){
        if(new RegExp("("+ k +")").test(fmt)){
            fmt = fmt.replace(RegExp.$1, (RegExp.$1.length===1) ? (o[k]) : (("00"+ o[k]).substr((""+ o[k]).length)));
        }
    }
    return fmt;
};


export default class Common {
    static SCREEN_WIDTH = screenWidth;
    static SCREEN_HEIGHT = screenHeight;
    static PIXEL_RATIO = pixelRatio;
    static DEFAULT_DENSITY = DEFAULT_DENSITY;


    //是否为iphoneX
    static isIphoneX = isIphoneX();


    //字体自适应大小
    static autoFontSize(size) {
        return autoFontSize(size);
    }


    //尺寸自适应大小
    static autoScaleSize(size) {
        return autoScaleSize(size);
    }


    //获取指定格式时间字符串
    static getDateFormat(date, format = false) {
        if (false !== format) {
            format = "yyyy-MM-dd HH:mm:ss";
        }
        return date.format(format);
    }
}

然后在App.js内渲染路由和tab,注意在路由外层要包一个View,以便后面我们使用全局的toast和loading,同时tab作为路由中的一个页整体呈现。

//自定义组件
import CustomTabBar from './components/customTabBar'; //自定义选项卡
//选项卡Tab页
import HomeTabScreen from './views/home'; //首页
import HeadsetTabScreen from './views/headset'; //试听
import BoughtTabScreen from './views/bought'; //已购
import MineTabScreen from './views/mine'; //我的
//页面
import SignInOrUpScreen from './views/signIns/signInOrUp'; //免注册登录
import SignInScreen from './views/signIns/signIn'; //登录

// const instructions = Platform.select({
//   ios: 'Press Cmd+R to reload,n' +
//     'Cmd+D or shake for dev menu',
//   android: 'Double tap R on your keyboard to reload,n' +
//     'Shake or press menu button for dev menu',
// });

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

    componentWillMount() {
        // Disable back button by just returning true instead of Action.pop()
        BackHandler.addEventListener('hardwareBackPress', () => {return true});
    }

    render() {
        let tabNames = ['首页', '试听', '已购', '我的'];
        return (}
                tabBarPosition='bottom'
            >);
    }
}

export default class App extends Component {
    render() {
        return ({/*首页(tab)*/}{/*登录*/});
    }
}

const styles = StyleSheet.create({
    router: {
        backgroundColor: '#e6e6e6',
    },
    root: {
        backgroundColor: '#e6e6e6',
    },
    title: {
        color: '#ffffff',
    },
});

这样就把路由和tab集成到一起了,关于路由的使用这里有个详解《react-native-router-flux使用技巧(API篇)》,我这里就说一些简单的跳转。

Actions.pop()

返回上一页。

Actions.key()

不带参跳转到键为key的页,Actions.key()中的key即为Scene的key属性值,如代码中的home和signInOrUp。


Actions.key(param)

带参数跳转到键为key的页,Actions.key()中的key即为Scene的key属性值,如代码中的home和signInOrUp。

参数可以通过属性获取,如this.props.param。


本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除。
换一批
延伸阅读

前端传递:表名 user,字段 username 字符串、age 数字、is_ikun 布尔,并且把这些值封装为了一个对象

关键字: 框架 前端

在这篇文章中,小编将为大家带来路由器的相关报道。如果你对本文即将要讲解的内容存在一定兴趣,不妨继续往下阅读哦。

关键字: 路由器 Router 路由

长途电话网(long distance network )可简称为长途网。它担负县以上城市之间的长途电话业务,也包括部分非话业务(如话路数据、用户传真等)。传输设施包括架空明线、电缆、光缆、载波系统、脉码调制设备以及无线...

关键字: 长途电话网 路由 交换中心

摘要:J2EE是目前企业开发的主流Java开发应用平台,文章主要介绍了轻量级J2EE中流行的Struts2、Spring和Hibernate三种框架。具体阐述了SSH框架的基本特征、优点以及SSH的无缝集成,并结合病房信...

关键字: 轻量级J2EE SSH 框架 无缝集成 病房信息管理系统

两台路由器的连接方法和无线路由桥接

关键字: 路由器 路由

摘 要:在无线体域网(WBAN)中,传感器采集到的数据都需要可靠的传递给相关医疗机构,而由于传感器中的电池容量有限。因此,探索随着传感器电量的变化,调整消息在节点中的传输路径,提高系统QoS(服务质量)的方法具有重要意义...

关键字: 无线体域网 路由 AODV 可靠性

本文中,小编将对路由器予以介绍,如果你想对路由器以及路由器的路由原理的详细情况有所认识,或者想要增进对路由器的了解程度,不妨请看以下内容哦。

关键字: 路由器 路由 网关

在软件研发这个领域,程序员的终极目标都是想成为一名合格的架构师。

关键字: 架构 框架 软件研发

在下述内容中,本文将对华硕电竞特工 TUF GAMING AX3000 刺客信条联名款路由的相关消息予以报道,一起来了解下它的具体情况吧。

关键字: 华硕 电竞特工 路由

在这篇文章中,小编将对京东云无线宝 360 WiFi 6 全屋路由加以介绍以增进大家对它的了解程度,和小编一起来看看吧。

关键字: 路由 芯片 Wi-Fi
关闭
关闭