I created a custom widget in flutter using custom painter. Its a status bar. I wanted to animate it, but now a problem is occurring that I don't know how to fix.
The bar consists of a line and several dots, depending on the status. When animating this bar, the line is correctly animated, but the dot is appearing to early, it just pops in.
example of how my widget is currently animating (can't post inline yet)
How can I choose when the dot animates?
This is the code I use for animating my widget:
class _StatusBarState extends State<StatusBar> with TickerProviderStateMixin {
late AnimationController _animationController;
@override
void initState() {
super.initState();
_animationController = AnimationController(
vsync: this,
duration: Duration(seconds: 1),
lowerBound: 1,
upperBound: widget.states.length.toDouble());
}
@override
void didUpdateWidget(covariant StatusBar oldWidget) {
super.didUpdateWidget(oldWidget);
_animationController.animateTo(widget.currentState.toDouble());
}
@override
Widget build(BuildContext context) {
return Column(
children: [
AnimatedBuilder(
animation: _animationController,
builder: (BuildContext buildContext, Widget? child) => Container(
height: 50,
width: MediaQuery.of(context).size.width * 0.75,
child: CustomPaint(
painter: _RentalStatusBarPainter(
context: context,
currentState: _animationController.value,
states: widget.states,
failed: widget.error),
),
),
),
Container(
width: MediaQuery.of(context).size.width * 0.85,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: widget.states
.map((e) => widget.states.indexOf(e) == widget.currentState - 1
? Text(
e,
style: Theme.of(context).textTheme.subtitle1,
)
: Text(
e,
style: Theme.of(context).textTheme.caption,
))
.toList(),
),
),
SizedBox(height: 10),
],
);
}
}
And this is the custom widget that is being painted:
@override
void paint(Canvas canvas, Size size) {
int currentStateInt = currentState.toInt();
final paint = Paint()
..color = Theme.of(context).cardColor
..style = PaintingStyle.stroke
..strokeWidth = 5
..strokeCap = StrokeCap.round;
final dotspaint = Paint()
..color = Theme.of(context).cardColor
..style = PaintingStyle.fill;
final filledpaint = Paint()
..color = failed
? Theme.of(context).colorScheme.error
: Theme.of(context).colorScheme.secondary
..style = PaintingStyle.stroke
..strokeWidth = 5
..strokeCap = StrokeCap.round;
final filleddotspaint = Paint()
..color = failed
? Theme.of(context).colorScheme.error
: Theme.of(context).colorScheme.secondary
..style = PaintingStyle.fill
..strokeCap = StrokeCap.round;
//draw the background
canvas.drawLine(
Offset(0, size.height / 2),
Offset(size.width, size.height / 2),
paint,
);
for (int i = 0; i < numberOfStates; i++) {
final double x = size.width * i / (numberOfStates - 1);
canvas.drawCircle(Offset(x, size.height / 2), 10, dotspaint);
}
//draw the filled out stuff
canvas.drawLine(
Offset(0, size.height / 2),
Offset(size.width * (currentState - 1) / (numberOfStates - 1),
size.height / 2),
filledpaint,
);
for (int i = 0; i < currentState; i++) {
final double x = size.width * i / (numberOfStates - 1);
canvas.drawCircle(Offset(x, size.height / 2), 10, filleddotspaint);
}
}
Any ideas or insights into how this "automatic" animation actually works is deeply appreciated!
Anton