博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
react-native 自定义倒计时按钮
阅读量:4083 次
发布时间:2019-05-25

本文共 7282 字,大约阅读时间需要 24 分钟。

最近研究了一下倒计时,网上有不少第三方开源库,不过试了试,有的并不好用,写法也停留在ES5上,而我写的demo使用的是0.45版本的RN,改起来很是麻烦。于是就参考实现了一下倒计时按钮,效果还不错~ http://www.jianshu.com/p/f5925a95c01b

一、效果图

1.ios效果图

QQ20170623-110612.gif
2.android效果图

QQ20170623-134441.png

二、基本原理

1.作为一个组件,要做到灵活可变:

我们将要使其样式、提示文字及显示方式可以自定义。那就要将文字样式,提示文字(包括显示的时间数字,时间单位等)都定义为组件属性,可以由调用者灵活定义。

2.基本原理:

首先用户输入一个结束时间,我们需要声明一个state,再写一个计时器,我们每隔1s就通过输入的结束时间和当前时间计算出时间差,再通过算法将时间差计算成xx天xx时xx分xx秒的格式,更改state的值,通过state的更改及判断计算结果,在render()方法中控制时间的显示及更新。

三、代码实现

(一)自定义倒计时组件

新建countDown.js

/** * Created by sybil052 on 2017/6/22. */import React, {    Component,    PropTypes,} from 'react';import {    StyleSheet,    View,    Text,} from 'react-native';const styles = StyleSheet.create({    text: {        fontSize: 30,        color: '#FFF',        marginLeft: 7,    },    container: {        flexDirection: 'row',    },    // 时间文字    defaultTime: {        paddingHorizontal: 3,        backgroundColor: '#555555',        fontSize: 12,        color: '#fff',        marginHorizontal: 3,        borderRadius: 2,    },    // 冒号    defaultColon: {        fontSize: 12,        color: '#555555'    },    // 提示    defaultTip: {        fontSize: 12,        color: '#555555',    }});class CountDown extends Component {    static displayName = 'Simple countDown';    // 属性    static propTypes = {        tip: PropTypes.string,        date: PropTypes.string,        days: PropTypes.objectOf(PropTypes.string),        hours: PropTypes.string,        mins: PropTypes.string,        segs: PropTypes.string,        onEnd: PropTypes.func,        containerStyle: View.propTypes.style,        daysStyle: Text.propTypes.style,        hoursStyle: Text.propTypes.style,        minsStyle: Text.propTypes.style,        secsStyle: Text.propTypes.style,        firstColonStyle: Text.propTypes.style,        secondColonStyle: Text.propTypes.style,        tipStyle: Text.propTypes.style,    };    // 默认属性    static defaultProps = {        date: new Date(),        days: {            plural: '天',            singular: '天',        },        hours: ':',        mins: ':',        segs: ':',        tip: '',        onEnd: () => {},        containerStyle: styles.container, // container 的style        daysStyle: styles.defaultTime, // 天数 字体的style        hoursStyle: styles.defaultTime, // 小时 字体的style        minsStyle: styles.defaultTime, // 分钟 字体的style        secsStyle: styles.defaultTime, // 秒数 字体的style        firstColonStyle: styles.defaultColon, // 从左向右 第一个冒号 字体的style        secondColonStyle: styles.defaultColon, // 从左向右 第2个冒号 字体的style        tipStyle: styles.defaultTip, // 提示字体style    };    state = {        days: 0,        hours: 0,        min: 0,        sec: 0,    };    componentDidMount() {        this.interval = setInterval(()=> {            const date = this.getDateData(this.props.date);            if (date) {                this.setState(date);            } else {                this.stop();                this.props.onEnd();            }        }, 1000);    }    componentWillMount() {        const date = this.getDateData(this.props.date);        if (date) {            this.setState(date);        }    }    componentWillUnmount() {        this.stop();    }    getDateData(endDate) {        endDate = endDate.replace(/-/g,"/");        console.log('end',new Date(endDate));        console.log('now',new Date);        // console.log('end===',Date.parse(new Date(endDate)));        // console.log('now===',Date.parse(new Date));        let diff = (Date.parse(new Date(endDate)) - Date.parse(new Date)) / 1000;        if (diff <= 0) {            return false;        }        // console.log('===========',diff);        const timeLeft = {            years: 0,            days: 0,            hours: 0,            min: 0,            sec: 0,            millisec: 0,        };        if (diff >= (365.25 * 86400)) {            timeLeft.years = Math.floor(diff / (365.25 * 86400));            diff -= timeLeft.years * 365.25 * 86400;        }        if (diff >= 86400) {            timeLeft.days = Math.floor(diff / 86400);            diff -= timeLeft.days * 86400;        }        if (diff >= 3600) {            timeLeft.hours = Math.floor(diff / 3600);            diff -= timeLeft.hours * 3600;        }        if (diff >= 60) {            timeLeft.min = Math.floor(diff / 60);            diff -= timeLeft.min * 60;        }        timeLeft.sec = diff;        return timeLeft;    }    render() {        const countDown = this.state;        let days;        if (countDown.days === 1) {            days = this.props.days.singular;        } else {            days = this.props.days.plural;        }        return (            
{ this.props.tip ?
{this.props.tip}
: null} { (countDown.days > 0) ?
{ this.leadingZeros(countDown.days)+days}
: null} { countDown.hours > 0 ?
{ this.leadingZeros(countDown.hours)}
: null} { countDown.hours > 0 ?
{this.props.hours}
: null}
{this.leadingZeros(countDown.min)}
{this.props.mins}
{this.leadingZeros(countDown.sec)}
{this.props.segs}
); } stop() { clearInterval(this.interval); } // 数字前面补0 leadingZeros(num, length = null) { let length_ = length; let num_ = num; if (length_ === null) { length_ = 2; } num_ = String(num_); while (num_.length < length_) { num_ = '0' + num_; } return num_; }}export default CountDown;
(二)具体使用

来说下我们要实现的效果,传入一个结束时间,开始倒计时,倒计时中,抢单按钮可以点击,当倒计时结束,按钮置灰且不可点击。

新建demo.js

/** * Created by sybil052 on 2017/6/19. */import React, {Component} from 'react';import {connect} from 'react-redux';import {    View,    Text,    StyleSheet,    TouchableOpacity,} from 'react-native';import CountDown from '../../components/countDown';class Demo extends Component {    constructor(props) {        super(props);        this.state={            isEnd: false        }    }    componentDidMount() {    }    render() {        return (            
{ alert('抢单'); }}>
抢单
{ this.setState({ isEnd: true }) }} />
); }}const styles =StyleSheet.create({ container: { flex: 1, backgroundColor: 'white' }, //时间文字 time: { paddingHorizontal: 2, fontSize: 13, color: 'white', textAlign: 'center', lineHeight: 17, }, //冒号 colon: { fontSize: 13, color:'white', textAlign: 'center', lineHeight: 17, }, tip:{ color: 'white', textAlign: 'center', fontSize: 13, lineHeight: 17 }});function mapStateToProps(state){ return {};}function mapDispatchToProps (dispatch){ return {};}export default connect(mapStateToProps, mapDispatchToProps)(Demo);

好了,自定义的倒计时按钮就写好了~希望对你们有所帮助!!!

转载地址:http://dyrni.baihongyu.com/

你可能感兴趣的文章
HDFS 纠删码
查看>>
基于柯西矩阵的Erasure Code技术详解
查看>>
基于范德蒙矩阵的Erasure code技术详解
查看>>
一个IO的传奇一生(12)-- 磁盘阵列1
查看>>
主定理的证明及应用举例
查看>>
线性判别分析(Linear Discriminant Analysis,LDA) 简单分析
查看>>
leetcode刷题(五):分治算法
查看>>
【算法】动态规划算法—买卖股票的最佳时机系列(1-4)
查看>>
想从事分布式系统,计算,hadoop等方面,需要哪些基础,推荐哪些书籍?--转自知乎
查看>>
【经验总结】如何找方向相关(计算机)的论文
查看>>
计算机论文查找
查看>>
计算机方向学术入门经验
查看>>
大牛博士是如何进行文献检索和阅读(好习惯受益终生)
查看>>
【转】台湾教授-如何阅读科研论文
查看>>
《如何写好科研论文》
查看>>
最大长方形 (Maximum Submatrix & Largest Rectangle)(涵盖各种求最大矩形题目)
查看>>
强连通分量之Kosaraju算法
查看>>
动态规划法(六)鸡蛋掉落问题(一)
查看>>
LeetCode 887.鸡蛋掉落(C++)
查看>>
Dijkstra‘s algorithm (C++)
查看>>