'Flutter AnimationController listener not firing

I am attempting to use an AnimationController in my Bloc to send a series of images every couple of seconds to the Stateful Widget. The following code snippets show the setup. Although the animation ticker fires(which I can see via the ticker print statements), the listener never executes.

Any ideas?

 class RaspDataBloc extends Bloc<RaspDataEvent, RaspDataState>
    implements TickerProvider {
   ...
    void startImageAnimation() {
    _forecastImageAnimationController = AnimationController(
        value: 0,
        duration: Duration(milliseconds: 15000),
        lowerBound: 0,
        upperBound: _forecastTimes.length.toDouble(),
        vsync: this)
      ..repeat()
      ..addListener(() {
        _postForecastImageSet(_forecastImageAnimationController.value);//  <<< doesn't execute
      });
    _forecastImageAnimationController.forward();
  }

  @override
  Ticker createTicker(onTick) {     //  <<<< This executes
    print('Creating Ticker');
    return Ticker(tickerDuration);
  }

  tickerDuration(Duration elapsed) {
    print('Ticker duration:  $elapsed.inMilliseconds'); //<<<< This fires regularly as expected
  }

  Stream<RaspDataState> _postForecastImageSet(double value) async* {
    print("Animation value: $_forecastImageAnimationController.value");
    var imageIndex = value.toInt();
    if (imageIndex < _imageSets.length) {
      print("Posting imageSet[$imageIndex]");
      yield new RaspForecastImageDisplay(_imageSets[imageIndex]);
    }
  }


Solution 1:[1]

Is there a special reason why you are using a TickerProvider? Typically with an AnimationController you use a SingleTickerProviderStateMixin. If you do that, and add the listener after creating the animation controller in your initState, then your listener will work. Like this:

class _MyStatefulWidgetState extends State<MyStatefulWidget> with SingleTickerProviderStateMixin {

  AnimationController _animationController;

  @override
  initState(){
    _animationController = AnimationController(
      vsync: this,
      duration: Duration(seconds: 2)
    );
    _animationController.addListener((){
      print('Animation Controller Listener');
    });
    super.initState();
  }

Solution 2:[2]

Hit the same problem just now, but the ticker works fine. You just have to start it.

Ticker class

Calls its callback once per animation frame.

When created, a ticker is initially disabled. Call start to enable the ticker.

https://api.flutter.dev/flutter/scheduler/Ticker-class.html

So basically:

TickerProvider provider; // get a TickerProvider from somewhere.
Ticker ticker = provider.createTicker((elapsed) => print('tick ($elapsed)'));
ticker.start();

which will result in something like:

I/flutter (28439): tick (0:00:00.000000)
I/flutter (28439): tick (0:00:00.050374)
I/flutter (28439): tick (0:00:00.067166)
I/flutter (28439): tick (0:00:00.218288)
I/flutter (28439): tick (0:00:00.235081)

Basically the time elapsed from the moment it started

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 Badro Niaimi
Solution 2