'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.

Aniamtion 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