flutter 倒计时组件


class ClockComponent extends StatefulWidget {
  final String? endTime;

  ClockComponent({
    Key? key,
    this.endTime,
  }) : super(key: key);

  @override
  _ClockComponentState createState() {
    return _ClockComponentState();
  }
}

class _ClockComponentState extends State<ClockComponent> {
  // 用来在布局中显示相应的剩余时间
  String remainTime = '';
  Timer? _timer;

  @override
  void initState() {
    super.initState();
    // 初始化的时候开启倒计时
    startCountDown(widget.endTime);
  }

  @override
  void dispose() {
    super.dispose();
    // 在页面回收或滑动复用回收的时候一定要把 timer 清除
    if (_timer != null) {
      if (_timer!.isActive) {
        _timer!.cancel();
        _timer = null;
      }
    }
  }

  @override
  void didUpdateWidget(ClockComponent oldWidget) {
    super.didUpdateWidget(oldWidget);
    // 外部重新请求接口后重新进行倒计时,这个方法是用来监控外部 setState 的
    startCountDown(widget.endTime);
  }

  void startCountDown(time) {
    var nowTime = DateTime.now();
    // var endTime = DateTime.parse(time.toString());
    var endTime = DateTime.parse(time);

    // 如果剩余时间已经不足一分钟,则不必计时,直接标记超时
    if (endTime.millisecondsSinceEpoch - nowTime.millisecondsSinceEpoch <
        1000 * 60) {
      setState(() {
        remainTime = '超时';
      });
      return;
    }

    // 重新计时的时候要把之前的清除掉
    if (_timer != null) {
      if (_timer!.isActive) {
        _timer!.cancel();
        _timer = null;
      }
    }

    const repeatPeriod = const Duration(milliseconds: 1000);

    calculateTime(nowTime, endTime);

    _timer = Timer.periodic(repeatPeriod, (timer) {
      //到时回调
      nowTime = nowTime.add(repeatPeriod);

      if (endTime.millisecondsSinceEpoch - nowTime.millisecondsSinceEpoch <
          1000 * 60) {
        //取消定时器,避免无限回调
        timer.cancel();
        // timer = null;

        setState(() {
          remainTime = '超时';
        });
        return;
      }
      calculateTime(nowTime, endTime);
    });
  }

  /// 计算天数、小时、分钟、秒
  void calculateTime(nowTime, endTime) {
    var _surplus = endTime.difference(nowTime);
    int day = (_surplus.inSeconds ~/ 3600) ~/ 24;
    int hour = (_surplus.inSeconds ~/ 3600) % 24;
    int minute = _surplus.inSeconds % 3600 ~/ 60;
    int second = _surplus.inSeconds % 60;

    var str = '';
    if (day > 0) {
      str = day.toString() + '天';
    }
    if (hour > 0 || (day > 0 && hour == 0)) {
      str = str + hour.toString() + '小时';
    }
    str = str + minute.toString() + '分钟';
    str = str + second.toString() + "秒";

    setState(() {
      remainTime = str;
    });
  }

  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return Container(
      child: Text("$remainTime"),
    );
  }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值