'Animation<double>?' can't be assigned to a variable of type 'Listenable'

Viewed 773

I am following a tutorial on how to animate a page view and show progress as one transitions from one page to another. Here is the question and answer Progress Bar Animation In PageView in Flutter

After writing the code I get an error that The argument type 'Animation<double>?' can't be assigned to the parameter type 'Listenable' and Try changing the type of the variable, or casting the right-hand type to 'Animation<double>'.

This is the code where I get the error

class AnimatedProgressBar extends AnimatedWidget {
  AnimatedProgressBar({Key? key, Animation<double>? animation})
      : super(key: key, listenable: animation);

  Widget build(BuildContext context) {
    final Animation<double> animation = listenable;
    return Container(
      height: 6.0,
      width: animation.value,
      decoration: BoxDecoration(color: Colors.white),
    );
  }
}

The specific lines with errors are

AnimatedProgressBar({Key? key, Animation<double>? animation}) : super(key: key, listenable: animation);

and final Animation<double> animation = listenable;

1 Answers

The property listenable is non-nullable which means that you need to use the null assertion operator ! or cast your animation as a non-nullable Listenable.

Moreover you need to cast back your listenable as Animation<double> when assigning it:

class AnimatedProgressBar extends AnimatedWidget {
  AnimatedProgressBar({Key? key, Animation<double>? animation})
      : super(
          key: key,
          listenable: animation!, // or `animation as Listenable`
        );

  @override
  Widget build(BuildContext context) {
    final animation = listenable as Animation<double>;
    return Container(
      height: 6.0,
      width: animation.value,
      decoration: const BoxDecoration(color: Colors.white),
    );
  }
}

Alternative

Instead of force casting your animation as a non-nullable you should make it required in your constructor so it cannot be null, then you wouldn't need the cast anymore:

class AnimatedProgressBar extends AnimatedWidget {
  const AnimatedProgressBar({
    Key? key,
    required Animation<double> animation, // Now required and cannot be null
  }) : super(
          key: key,
          listenable: animation, // No need to cast anymore
        );

  @override
  Widget build(BuildContext context) {
    final animation = listenable as Animation<double>; // Still need to cast here
    return Container(
      height: 6.0,
      width: animation.value,
      decoration: const BoxDecoration(color: Colors.white),
    );
  }
}
Related