Search code examples
animationdartflutter

Listen for an animation to complete


I'm trying to perform an action after my animation finishes. I tried adding a statusListener but that is not working for me. My code looks like this:

  @override
  void initState() {
    super.initState();
    _controller = new AnimationController(
      duration: new Duration(milliseconds: 500),
      vsync: this,
    )..addStatusListener((AnimationStatus status) {
      print("Going");
      if (status.index == 3 && spins > 0) { // AnimationStatus index 3 == completed animation
        _controller.duration = new Duration(milliseconds: speed - 50);
        _controller.forward(from: _controller.value == null ? 0.0 : 1 - _controller.value);
        spins--;
        print(speed);
      }
    });
  }

The print(Going); never gets executed but my animation does end. What is going wrong?

///---Edit---///

I'm using an AnimatedBuilder, that part of the code looks like this:

child: new AnimatedBuilder(
  animation: _controller,
  child: new Image.network(widget.url),
  builder: (BuildContext context, Widget child) {
    return new Transform.rotate(
      angle: _controller.value * 2.0 * math.PI,
      child: child,
    );
  },
),

Solution

  • Reacting to your comment and edit I looked into the AnimationBuilder. Adapting the example in the docs I came up with this working solution:

    class Spinner extends StatefulWidget {
      @override
      _SpinnerState createState() => new _SpinnerState();
    }
    
    class _SpinnerState extends State<Spinner> with SingleTickerProviderStateMixin {
      AnimationController _controller;
      CurvedAnimation _animation;
    
      @override
      void initState() {
        super.initState();
        _controller = new AnimationController(
          duration: const Duration(seconds: 5),
          vsync: this,
        )..forward();
    
        _animation = new CurvedAnimation(
            parent: _controller,
            curve: Curves.linear,
        )..addStatusListener((AnimationStatus status) {
          if (status == AnimationStatus.completed)
            print('completed');
        });
      }
    
      @override
      void dispose() {
        _controller.dispose();
        super.dispose();
      }
    
      @override
      Widget build(BuildContext context) {
        return new AnimatedBuilder(
          animation: _animation,
          child: new Container(width: 200.0, height: 200.0, color: Colors.green),
          builder: (BuildContext context, Widget child) {
            return new Transform.rotate(
              angle: _controller.value * 2.0 * 3.1415,
              child: child,
            );
          },
        );
      }
    }
    

    As you can see, I used the controller as parent to an animation, which was than used as animation for the AnimationBuilder. Hope it helps.