RN 中的秒杀倒计时功能实现 (react_native_countdowntimer)

倒计时控件,只需要添加一个结束时间。适用于商品秒杀页面等等。
这里有三种样式的倒计时模式,废话不多上,直接上码

1. 导入依赖:

npm install react_native_countdowntimer --save

2.定义一个使用类: ( CountDownPage.js )

import React, { Component, PropTypes } from 'react'
import {
    StyleSheet,
    TouchableHighlight,
    Image,
    Text,
    View,
} from 'react-native';
import CountDownReact from './CountDownReact'

const appDemo = React.createClass({


  render() {
    return <View style={[{paddingTop:40, marginTop:70}]}>
      {/*1.*/}
      <CountDownReact
          //date={new Date(parseInt(seckill.endTime))}
          date="2017-11-28T00:00:00+00:00"
          days={{plural: 'Days ',singular: 'day '}}
          hours=':'
          mins=':'
          segs=''

          daysStyle={styles.time}
          hoursStyle={styles.time}
          minsStyle={styles.time}
          secsStyle={styles.time}
          firstColonStyle={styles.colon}
          secondColonStyle={styles.colon}
      />

      {/*2.*/}
      <View style={{
                flexDirection: 'row',
                alignItems:'baseline',
                marginTop:20,
            }}>
        <Text style={styles.cardItemTimeRemainTxt}>还剩</Text>
        <CountDownReact
            //date={new Date(parseInt(seckill.endTime))}
            date="2017-11-28T00:00:00+00:00"
            days={{plural: '天 ',singular: '天 '}}
            hours=':'
            mins=':'
            segs=''

            daysStyle={styles.cardItemTimeRemainTxt}
            hoursStyle={styles.cardItemTimeRemainTxt}
            minsStyle={styles.cardItemTimeRemainTxt}
            secsStyle={styles.cardItemTimeRemainTxt}
            firstColonStyle={styles.cardItemTimeRemainTxt}
            secondColonStyle={styles.cardItemTimeRemainTxt}
        />
      </View>

      {/*3.*/}
      <CountDownReact
          //date={new Date(parseInt(seckill.endTime))}
          date="2017-11-28T00:00:00+00:00"
          days={{plural: 'D ',singular: 'D '}}
          hours=':'
          mins=':'
          segs=''

          containerStyle={styles.container}
          daysStyle={styles.text}
          hoursStyle={styles.text}
          minsStyle={styles.text}
          secsStyle={styles.text}
          firstColonStyle={styles.text}
          secondColonStyle={styles.text}
      />


      {/*4.*/}
      <View style={styles.cardItem}>
        <Image source={{uri: 'http://www.ishuyin.com/data/images/nopic.gif'}}
               style={styles.cardItemMainPic} backgroundColor={'#'+Math.floor(Math.random()*16777215).toString(16)}/>
        <View style={styles.cardItemMask}>
          <View style={styles.cardItemTimer}>
            <Image style={styles.cardItemTimerIcon}
                   source={{uri: 'http://www.qiyipic.com/common/fix/gmjy3/images/groupontimeredicon.png'}}/>
            <View style={{
                flexDirection: 'row',
                alignItems:'baseline'
            }}>
              <Text style={styles.cardItemTimeRemainTxt}>还剩</Text>
              <CountDownReact
                  //date={new Date(parseInt(seckill.endTime))}
                  date="2017-10-28T00:00:00+00:00"
                  days={{plural: '天 ',singular: '天 '}}
                  hours=':'
                  mins=':'
                  segs=''

                  daysStyle={styles.cardItemTimeRemainTxt}
                  hoursStyle={styles.cardItemTimeRemainTxt}
                  minsStyle={styles.cardItemTimeRemainTxt}
                  secsStyle={styles.cardItemTimeRemainTxt}
                  firstColonStyle={styles.cardItemTimeRemainTxt}
                  secondColonStyle={styles.cardItemTimeRemainTxt}
              />
            </View>
          </View>

        </View>
      </View>
    </View>
  }
});


const styles = StyleSheet.create({

  cardItemTimeRemainTxt: {
    fontSize: 20,
    color: '#ee394b'
  },
  container: {
    backgroundColor: '#000',
    padding: 5,
    borderRadius: 5,
    flexDirection: 'row',
    marginTop:20
  },
  text: {
    fontSize: 30,
    color: '#FFF',
    marginLeft: 7,
  },
  //时间文字
  time: {
    paddingHorizontal: 3,
    backgroundColor: 'rgba(85, 85, 85, 1)',
    fontSize: 12,
    color: 'white',
    marginHorizontal: 3,
    borderRadius: 2,
  },
  //冒号
  colon: {
    fontSize: 12, color: 'rgba(85, 85, 85, 1)'
  },

  cardItemMask:{
    position: 'absolute',
    top: 15,
    right:10,
    backgroundColor: 'transparent'
  },
  cardItemTimer:{
    flexDirection: 'row',
    alignItems: 'center'
  },
  cardItemTimerIcon: {
    width:11,
    height: 11,
  },
  cardItem: {
    flex:1,
    flexDirection: 'column',
    backgroundColor:'red',
    marginTop:20,
    width: 370,
    height: 370 * 0.65625,
  },
  cardItemMainPic: {
     width: 370,
    height: 370 * 0.65625,
  },
});

export default appDemo

3. 定义一个倒计时的工具类:( CountDownReact.js )

import React, {
    Component,
    PropTypes,
} from 'react';

import {
    StyleSheet,
    View,
    Text,
    Image,
} from 'react-native';

const styles = StyleSheet.create({
  cardItemTimeRemainTxt: {
    fontSize: 20,
    color: '#ee394b'
  },
  text: {
    fontSize: 30,
    color: '#FFF',
    marginLeft: 7,
  },
  container: {
    flexDirection: 'row',
  },
  //时间文字
  defaultTime: {
    paddingHorizontal: 3,
    backgroundColor: 'rgba(85, 85, 85, 1)',
    fontSize: 12,
    color: 'white',
    marginHorizontal: 3,
    borderRadius: 2,
  },
  //冒号
  defaultColon: {
    fontSize: 12, color: 'rgba(85, 85, 85, 1)'
  }
});

class CountDown extends Component {
  static displayName = 'Simple countDown';
  static propTypes = {
    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,

  };
  static defaultProps = {
    date: new Date(),
    days: {
      plural: '天',
      singular: '天',
    },
    hours: ':',
    mins: ':',
    segs: ':',
    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

  };
  state = {
    days: 0,
    hours: 0,
    min: 0,
    sec: 0,
  };
  componentDidMount() {
    //console.log(this.props.date);//"2017-03-29T00:00:00+00:00"
    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) {
    let diff = (Date.parse(new Date(endDate)) - Date.parse(new Date)) / 1000;

    if (diff <= 0) {
      return false;
    }

    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 (
    //    <View style={styles.container}>
    //      <Text style={styles.text}>{
    //        ((countDown.days > 0) ? this.leadingZeros(countDown.days)+days:'')
    //        +this.leadingZeros(countDown.hours)
    //        +':'+this.leadingZeros(countDown.min)
    //        +':'+this.leadingZeros(countDown.sec)}</Text>
    //    </View>
    //
        <View style={this.props.containerStyle}>
          { (countDown.days>0) ? <Text style={this.props.daysStyle}>{ this.leadingZeros(countDown.days)+days}</Text> : null}
          <Text style={this.props.hoursStyle}>{ this.leadingZeros(countDown.hours)}</Text>
          <Text style={ this.props.firstColonStyle}>:</Text>
          <Text style={this.props.minsStyle}>{this.leadingZeros(countDown.min)}</Text>
          <Text style={this.props.secondColonStyle}>:</Text>
          <Text style={this.props.secsStyle}>{this.leadingZeros(countDown.sec)}</Text>
          <Text style={this.props.secondColonStyle}>'</Text>
        </View>


    );
  }
  stop() {
    clearInterval(this.interval);
  }
  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;

4. 直接使用 CountDownPage.js 即可

运行效果:

倒计时

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小毅哥哥

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值