Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to create gradient progress indicator like this?

Tags:

flutter

I noticed that the basic CircularProgressIndicator widget has very few parameters to customize it. I would like to achieve a result like on the gif. Unfortunately, my knowledge isn't enough to create such an indicator from scratch, searches on pub.dev didn't bring any results.

enter image description here

like image 241
Smith Avatar asked Jul 11 '26 10:07

Smith


1 Answers

  • Make a CustomPainter to draw the circle. Use SweepGradient(...).createShader(...) to apply the gradient effect.

  • Wrap the widget with a RotationTransition to make the widget spin.

  • Make an animation for spinning the widget.

Code:

The circular progress indicator widget:

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;
  }
}

Animation controller:

AnimationController _animationController;

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

Usage:

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

Result:

res

like image 52
Mobina Avatar answered Jul 14 '26 15:07

Mobina



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!