Custom animated progress bar widget

This widget displays a customizable progress bar that animates over a set duration. It allows you to specify the width, height, fill and unfill colors, border radius, text size, and text color. The progress is visually represented as a percentage, and when the animation completes, an optional actionAtEnd callback can be triggered, allowing you to execute a custom action.

No need any import

class ProgressBarAnimated extends StatefulWidget {
  const ProgressBarAnimated({
    super.key,
    this.width,
    this.height,
    required this.colorFill,
    required this.colorUnFill,
    required this.seconds,
    required this.bordeRadious,
    required this.textSize,
    required this.textColor,
    this.actionAtEnd,
  });

  final double? width;
  final double? height;
  final Color colorFill;
  final Color colorUnFill;
  final int seconds;
  final int bordeRadious;
  final double textSize;
  final Color textColor;
  final Future Function()? actionAtEnd;

  @override
  State<ProgressBarAnimated> createState() => _ProgressBarAnimatedState();
}

class _ProgressBarAnimatedState extends State<ProgressBarAnimated>
    with SingleTickerProviderStateMixin {
  late AnimationController _controller;

  @override
  void initState() {
    super.initState();
    _controller = AnimationController(
      duration: Duration(seconds: widget.seconds),
      vsync: this,
    )..forward();

    _controller.addStatusListener((status) async {
      if (status == AnimationStatus.completed) {
        if (widget.actionAtEnd != null) {
          await widget.actionAtEnd!();
        }
      }
    });
  }

  @override
  void dispose() {
    _controller.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Container(
      width: widget.width ?? double.infinity,
      height: widget.height ?? 20.0,
      decoration: BoxDecoration(
        color: widget.colorUnFill,
        borderRadius: BorderRadius.circular(widget.bordeRadious.toDouble()),
      ),
      child: AnimatedBuilder(
        animation: _controller,
        builder: (context, child) {
          return Stack(
            children: [
              Positioned.fill(
                child: FractionallySizedBox(
                  widthFactor: _controller.value,
                  child: Container(
                    decoration: BoxDecoration(
                      color: widget.colorFill,
                      borderRadius:
                          BorderRadius.circular(widget.bordeRadious.toDouble()),
                    ),
                  ),
                ),
              ),
              Center(
                child: Text(
                  '${(_controller.value * 100).toInt()}%',
                  style: TextStyle(
                    color: widget.textColor,
                    fontSize: widget.textSize,
                    fontWeight: FontWeight.bold,
                  ),
                ),
              ),
            ],
          );
        },
      ),
    );
  }
}

If you liked it, leave your comment and like. ๐Ÿ˜ƒ

6