如何创建这样的渐变进度指示器?

时间:2020-08-27 11:26:06

标签: flutter

我注意到基本的CircularProgressIndicator小部件几乎没有参数可以对其进行自定义。我想获得类似gif的结果。不幸的是,我的知识还不足以从头开始创建这样的指标,在​​pub.dev上的搜索未带来任何结果。

enter image description here

1 个答案:

答案 0 :(得分:2)

  • 进行CustomPainter绘制圆。使用SweepGradient(...).createShader(...)来应用渐变效果。

  • RotationTransition包裹小部件以使其旋转。

  • 制作动画以旋转小部件。

代码:

循环进度指示器小部件:

class GradientCircularProgressIndicator extends StatelessWidget {
  final double radius;
  final List<Color> gradientColors;
  final double strokeWidth;

  GradientCircularProgressIndicator({
    @required this.radius,
    @required this.gradientColors,
    this.strokeWidth = 10.0,
  });

  @override
  Widget build(BuildContext context) {
    return CustomPaint(
      size: Size.fromRadius(radius),
      painter: GradientCircularProgressPainter(
        radius: radius,
        gradientColors: gradientColors,
        strokeWidth: strokeWidth,
      ),
    );
  }
}

class GradientCircularProgressPainter extends CustomPainter {
  GradientCircularProgressPainter({
    @required this.radius,
    @required this.gradientColors,
    @required this.strokeWidth,
  });
  final double radius;
  final List<Color> gradientColors;
  final double strokeWidth;

  @override
  void paint(Canvas canvas, Size size) {
    size = Size.fromRadius(radius);
    double offset = strokeWidth / 2;
    Rect rect = Offset(offset, offset) &
        Size(size.width - strokeWidth, size.height - strokeWidth);
    var paint = Paint()
      ..style = PaintingStyle.stroke
      ..strokeWidth = strokeWidth;
    paint.shader =
        SweepGradient(colors: gradientColors, startAngle: 0.0, endAngle: 2 * pi)
            .createShader(rect);
    canvas.drawArc(rect, 0.0, 2 * pi, false, paint);
  }

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

动画控制器:

AnimationController _animationController;

  @override
  void initState() {
    _animationController =
        new AnimationController(vsync: this, duration: Duration(seconds: 1));
    _animationController.addListener(() => setState(() {}));
    _animationController.repeat();
    super.initState();
  }

用法:

RotationTransition(
  turns: Tween(begin: 0.0, end: 1.0).animate(_animationController),
  child: GradientCircularProgressIndicator(
    radius: 50,
    gradientColors: [
      Colors.white,
      Colors.red,
    ],
    strokeWidth: 10.0,
  ),
),

结果:

res