'How to find a Flutter widget has been rendered or not after animation completed
I have a scenario to find whether a widget has been rendered or not. I have tested with WidgetsBinding and SchedulerBinding for a custom painter, they got triggered after the widget gets rendered irrespective of animation. If the widget's animation is in progress before animation gets completed the event got triggered. In the below gif image, you can find the line is getting animated before that event triggers. So, is there any way to find out after the animation got completed? Kindly suggest me a way to achieve my requirement. I have attached a sample reference code and gif image.
import 'package:flutter/material.dart';
void main() {
return runApp(Line());
}
class Line extends StatefulWidget {
@override
State<StatefulWidget> createState() => _LineState();
}
class _LineState extends State<Line> with SingleTickerProviderStateMixin {
double _progress = 0.0;
Animation<double>? animation;
late DateTime startTime;
@override
void initState() {
startTime = DateTime.now();
WidgetsBinding.instance?.addPostFrameCallback((_) {
final DateTime endTime = DateTime.now();
final Duration duration = endTime.difference(startTime);
print(
'Duration to render the custom painter: ${duration.inMilliseconds}');
});
var controller = AnimationController(
duration: Duration(milliseconds: 5000), vsync: this);
animation = Tween(begin: 1.0, end: 0.0).animate(controller)
..addListener(() {
setState(() {
_progress = animation!.value;
});
});
controller.forward();
super.initState();
}
@override
Widget build(BuildContext context) {
return Container(
color: Colors.white,
child: CustomPaint(painter: LinePainter(_progress)));
}
}
class LinePainter extends CustomPainter {
Paint? _paint;
double _progress;
LinePainter(this._progress) {
_paint = Paint()
..color = Colors.teal
..strokeWidth = 8.0;
}
@override
void paint(Canvas canvas, Size size) {
canvas.drawLine(
Offset(0.0, 0.0),
Offset(size.width - size.width * _progress,
size.height - size.height * _progress),
_paint!);
}
@override
bool shouldRepaint(LinePainter oldDelegate) {
return oldDelegate._progress != _progress;
}
}
Thanks in advance.
Solution 1:[1]
As I can see you have already added a listener to your animation
animation = Tween(begin: 1.0, end: 0.0).animate(controller)
..addListener(() {
setState(() {
_progress = animation!.value;
});
});
Every time the value change on the animation, this listener is called, so the easy way to obtain your status is to check there the animation controller status
https://api.flutter.dev/flutter/animation/AnimationStatus.html
in your listener, you can just add a check and act according.
animation = Tween(begin: 1.0, end: 0.0).animate(controller)
..addListener(() {
if(controller.status == AnimationStatus.completed) {
// ADD YOUR LOGIC HERE
}
setState(() {
_progress = animation!.value;
});
});
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | CLucera |

