Flutter: 倒计时组件

import 'dart:async';
import 'dart:math';

import 'package:flutter/animation.dart';
import 'package:flutter/material.dart';

/// 倒计时

typedef DownTimeEndListener = void Function();

class DownTimeWidget extends StatefulWidget {
  Color clors;
  double width;
  double strokeWidth;
  int time;
  TextStyle textStyle;
  DownTimeEndListener endListener;

  DownTimeWidget(
      {Key key,
      this.clors,
      this.width,
      this.strokeWidth,
      this.time,
      this.textStyle,
      this.endListener})
      : super();

  @override
  _DownTimeWidgetState createState() => _DownTimeWidgetState();
}

class _DownTimeWidgetState extends State<DownTimeWidget>
    with TickerProviderStateMixin {
  int _time;
  AnimationController controller;
  CurvedAnimation curvedAnimation;
  Tween<double> animationTween;
  Animation<double> animation;
  double angle;

  @override
  void initState() {
    super.initState();
    _time = (widget.time / 1000).toInt();
    controller = new AnimationController(
        vsync: this, duration: Duration(milliseconds: widget.time));
    curvedAnimation =
        new CurvedAnimation(parent: controller, curve: Curves.linear);
    animationTween = new Tween(begin: 0.0, end: 360.0);
    animation = animationTween.animate(curvedAnimation);

    animation.addStatusListener((status) {
      //动画播放完成
      if (status == AnimationStatus.completed) {
        widget.endListener();
      }
    });

    animation.addListener(() {
      angle = animation.value;
      setState(() {});
    });
    controller.forward();
  }

  @override
  Widget build(BuildContext context) {
    return Container(
      width: widget.width,
      height: widget.width,
      decoration: BoxDecoration(
          borderRadius: BorderRadius.circular(widget.width / 2),
          color: Colors.white),
      child: Stack(
        children: [
          Center(
            child: DownTimeText(
              time: _time,
              textStyle: widget.textStyle,
            ),
          ),
          CustomPaint(
            painter: new DrawArcPainter(
              colors: widget.clors,
              angle: angle,
              width: widget.width,
            ),
          ),
        ],
      ),
    );
  }

  @override
  void dispose() {
    controller.dispose();
    animation.removeListener(null);
    super.dispose();
  }
}

///进度条
class DrawArcPainter extends CustomPainter {
  DrawArcPainter({this.colors, this.angle, this.width, this.mStrokeWidth});

  Color colors;

  double mStrokeWidth;

  double width;

  double angle;

  double angleToRadian(double angle) => angle * (pi / 180.0);

  double radianToAngle(double radian) => radian * (180.0 / pi);

  @override
  void paint(Canvas canvas, Size size) {
    Paint paint = new Paint()
      ..color = colors == null ? Colors.red : colors
      ..strokeWidth = mStrokeWidth == null ? 2.0 : mStrokeWidth
      ..style = PaintingStyle.stroke
      ..strokeCap = StrokeCap.round;
    Rect rect = new Rect.fromLTWH(0.0, 0.0, width, width);
    canvas.drawArc(rect, 0.0, angleToRadian(angle), false, paint);
  }

  @override
  bool shouldRepaint(CustomPainter oldDelegate) {
    return true;
  }
}

///时间
class DownTimeText extends StatefulWidget {
  int time;
  TextStyle textStyle;

  DownTimeText({Key key, this.time, this.textStyle}) : super(key: key);

  @override
  _DownTimeTextState createState() => _DownTimeTextState();
}

class _DownTimeTextState extends State<DownTimeText> {
  int _time;
  Timer timer;

  @override
  void initState() {
    super.initState();
    _time = widget.time;
    startDownTimer();
  }

  ///倒计时
  void startDownTimer() {
    timer = Timer.periodic(Duration(seconds: 1), (time) {
      if (_time == null || _time == 0) {
        setState(() {});
        timer?.cancel();
        return;
      }
      _time--;

      setState(() {});
    });
  }

  @override
  Widget build(BuildContext context) {
    return Text(
      "倒计时:$_time",
      style: widget.textStyle,
    );
  }

  @override
  void dispose() {
    timer.cancel();
    super.dispose();
  }
}
child: Container(
            margin: EdgeInsets.all(10.0),
            child: DownTimeWidget(clors: Colors.red,time: 5000,width: 50,strokeWidth: 5.0,
              textStyle: TextStyle(color: Colors.black,fontSize: 8.0
                  ,decoration:TextDecoration.none ),
              endListener: (){
                showNextPage();
              },),
          ),

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值