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,
),
),
),
],
);
},
),
);
}
}