当前位置:首页 > 芯闻号 > 充电吧
[导读]先来看下效果:这里需要用到两个第三方插件: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。

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

SAP(思爱普)近日发出的裁员计划,不仅涉及全球范围内约8000个职位,更是在中国区造成了近1500名正式员工和合同工不续的情况。

关键字: 软件 互联网

业内消息,近日Alphabet旗下谷歌公司发言人表示为控制成本正在进行最新裁员,但具体人数不详。该发言人表示,裁员并非全公司范围,受影响的员工将能够申请内部职位,但没有具体说明受影响的员工人数或涉及的团队。

关键字: 谷歌 裁员

几天前,以南印度组织零售商协会(ORA)为代表的20多家零售连锁店和4300家商店宣布将从5月1日起停止销售一加设备。4月17日,全印度移动零售商协会(AIMRA)代表印度15万多家线下智能手机零售商通知一加,其成员正在...

关键字: 印度 一加 小米 Poco

业内消息,近日光刻机制造商阿斯麦(ASML)公布了2024年第一季度业绩,财报显示,该公司当季总净销售额53亿欧元,环比下降27%;毛利率51.0%,上季度为51.4%;净利润12亿欧元(当前约92.4亿元人民币),环比...

关键字: 光刻机 ASML

近日有韩媒称,由于薪资谈判破裂,劳资双方未能缩小对涨薪的意见分歧,三星电子全国工会(NSEU)即日起将发起公司成立以来首次集体行动,工会当天在华城市(Hwaseong)京畿道华城园区的组件研究大楼(DSR)前举行文化活动...

关键字: 三星

昨天上午,华为终端官微宣布全新重磅新机开售,约一分钟线上即告售罄,线下门店排起长队,气势丝毫不输苹果,和 Mate 60 Pro 一样没有发布会,这次官方同样推出了 “HUAWEI Pura 70 系列 先锋计划”,可以...

关键字: 麒麟芯片 华为

上海2024年4月16日 /美通社/ -- 4月14日,为期四天的第89届中国国际医疗器械博览会(CMEF)盛大收官。澳鹏Appen很荣幸再次作为唯一的人工智能训练数据参展商参与此次"航母级"规模医疗...

关键字: APP 医疗器械 PEN 模型

基于大语言模型研发的品牌定制化AI客服解决方案,获得业界高度认可 上海2024年4月16日 /美通社/ -- transcosmos集团(中文名:大宇宙集团;以下简称:transcosmos)于2024年4月11日在C...

关键字: TRANS TI COSMOS AI

针对光伏优化器(MPPT)的非隔离DC-DC升压电路,推荐瑞森半导体低压MOS-SGT系列。极低导通电阻,低损耗,高雪崩耐量,高效率,非常适合高频应用。

关键字: 光伏优化器 MPPT

IDC近日发布的全球智能手机市场初步数据显示,苹果iPhone全球销量在今年一季度的销量下降了9.6%。

关键字: iPhone 苹果 端侧AI
关闭
关闭