React Native之倒计时组件的实现(ios android)
React Native之倒计时组件的实现(ios android)
一,需求分析
1,app需实现类似于淘宝的活动倒计时,并在倒计时结束时,活动也结束。
2,实现订单倒计时,并在倒计时结束时,订单关闭交易。
3,实现获取验证码倒计时。
二,技术实现
2.1,活动倒计时与订单倒计时的实现,源码如下:
- 1 componentDidMount() {
- 2 this.interval = setInterval(() => {
- 3 const date = this.getDateData(this.props.date);
- 4 if (date) {
- 5 this.setState(date);
- 6 } else {
- 7 this.stop();
- 8 this.props.onEnd();
- 9 }
- 10 }, 1000);
- 11 }
- 12 componentWillMount() {
- 13 const date = this.getDateData(this.props.date);
- 14 if (date) {
- 15 this.setState(date);
- 16 }
- 17 }
1,倒计时方法的实现:
- 1 getDateData(endDate) {
- 2 endDate = endDate.replace(/-/g, "/");
- 3 let diff = (Date.parse(new Date(endDate)) - Date.parse(new Date)) / 1000;
- 4 if (!!this.props.isOrederTime) {
- 5 diff = (Date.parse(new Date(endDate)) + (Number(this.props.isOrederTime) * 60 * 1000) - Date.parse(new Date)) / 1000;
- 6 }
- 7
- 8 if (diff <= 0) {
- 9 return false;
- 10 }
- 11 const timeLeft = {
- 12 years: 0,
- 13 days: 0,
- 14 hours: 0,
- 15 min: 0,
- 16 sec: 0,
- 17 millisec: 0,
- 18 };
- 19
- 20 if (diff >= (365.25 * 86400)) {
- 21 timeLeft.years = Math.floor(diff / (365.25 * 86400));
- 22 diff -= timeLeft.years * 365.25 * 86400;
- 23 }
- 24 if (diff >= 86400) {
- 25 timeLeft.days = Math.floor(diff / 86400);
- 26 diff -= timeLeft.days * 86400;
- 27 }
- 28 if (diff >= 3600) {
- 29 timeLeft.hours = Math.floor(diff / 3600);
- 30 diff -= timeLeft.hours * 3600;
- 31 }
- 32 if (diff >= 60) {
- 33 timeLeft.min = Math.floor(diff / 60);
- 34 diff -= timeLeft.min * 60;
- 35 }
- 36 timeLeft.sec = diff;
- 37 return timeLeft;
- 38 }
2,退出界面,清除定时器
- 1 componentWillUnmount() {
- 2 this.stop();
- 3 }
- 4
- 5 stop() {
- 6 clearInterval(this.interval);
- 7 }
3,数字不足时前面补0
- 1 // 数字前面补0
- 2 leadingZeros(num, length = null) {
- 3 let length_ = length;
- 4 let num_ = num;
- 5 if (length_ === null) {
- 6 length_ = 2;
- 7 }
- 8 num_ = String(num_);
- 9 while (num_.length < length_) {
- 10 num_ = '0' + num_;
- 11 }
- 12 return num_;
- 13 }
2.2,验证码倒计时与输入框
1,倒计时的实现(I18n 语言国际化),Api.sendVerifyCode调用后台发送验证码接口
- 1 //倒计时
- 2 daoJClick() {
- 3 //判断是否点击获取验证码
- 4 if(this.props.isClick){
- 5 this.props.isClick()
- 6 }
- 7
- 8 if (this.props.mobile === '') {
- 9 Toast.show(I18n.t('Signin.Please_enter_phone_number'));
- 10 return;
- 11 }
- 12 if (!(/^1[345678]\d{9}$/.test(this.props.mobile))) {
- 13 Toast.show(I18n.t('Signin.pla_rightphoneNumber'));
- 14 return
- 15 }
- 16 if(this.state.isDisable){
- 17 return
- 18 }
- 19 Api.sendVerifyCode(this.props.mobile)
- 20 .then((data) => {
- 21 Toast.show(I18n.t('Signin.Verification_code_transmission_success'))
- 22
- 23 }).catch((e) => {
- 24 });
- 25 this.setState({
- 26 isDisable: false,
- 27 });
- 28 const codeTime = this.state.timerCount -1;
- 29 const now = Date.now();
- 30 const overTimeStamp = now + codeTime * 1000 + 100;
- 31 /*过期时间戳(毫秒) +100 毫秒容错*/
- 32 this.interval = setInterval(() => {
- 33 /* 切换到后台不受影响*/
- 34 const nowStamp = Date.now();
- 35 if (nowStamp >= overTimeStamp) {
- 36 /* 倒计时结束*/
- 37 this.interval && clearInterval(this.interval);
- 38 this.setState({
- 39 timerCount: codeTime,
- 40 timerTitle: I18n.t('Signin.Get_verifying_code'),
- 41 isDisable: false,
- 42 });
- 43 } else {
- 44 const leftTime = parseInt((overTimeStamp - nowStamp) / 1000, 10);
- 45 this.setState({
- 46 timerCount: leftTime,
- 47 timerTitle: `(${leftTime})s`,
- 48 isDisable: true,
- 49 });
- 50 }
- 51 /* 切换到后台 timer 停止计时 */
- 52 }, 1000)
- 53 }
2,界面功能实现
- 1 <InputView
- 2 {...this.props}
- 3 returnKeyLabel={this.props.returnKeyLabel}
- 4 returnKeyType={this.props.returnKeyType}
- 5 align={this.props.align}
- 6 value={this.props.pin}
- 7 name={this.props.name}
- 8 hintText={this.props.hintText}
- 9 funcDisabled={this.state.isDisable}
- 10 onChangeText={this.props.onChangeText}
- 11 funcName={this.state.timerTitle}
- 12 funcOnPress={() => this.daoJClick()}/>
- 13 );
三,应用实例
3.1 活动与订单倒计时应用
- 1 import CountDown from "../CountDown";
- 2 <CountDown
- 3 date={endtime}
- 4 days={{ plural: '天 ', singular: '天 ' }}
- 5 onEnd={() => {
- 6 this.setState({
- 7 isEnd: true
- 8 })
- 9 }}
- 10 textColor={AppSetting.BLACK}
- 11 isHaveword={true}//是否有汉字
- 12 backgroundColor={'red'}
- 13 isOrederTime={AppSetting.OREDER_END_TIME}//是否是订单
- 14 textSize={AdaptationModel.setSpText(Platform.OS === 'ios' ? 18 : 20)}
- 15 />
界面效果
3.2 验证码倒计时
- 1 import VeriCodeInput from "/VeriCodeInput";
- 2
- 3 <VeriCodeInput
- 4 style={styles.input}
- 5 inputStyle={{ color: 'white' }}
- 6 align={'center'}
- 7 value={this.state.captcha}
- 8 mobile={this.state.mobile}
- 9 backgroundColor={'transparent'}
- 10 funcNameStyle={{ color: AppSetting.GREEN }}
- 11 hintText={I18n.t('Signin.Please_enter_verification_code')}
- 12 isClick={() => { this.isinputverification() }}
- 13 onChangeText={(text) => this.setState({ captcha: text })} />
界面效果