title: Flutter Animtion crash with The following assertion was thrown while notifying listeners for AnimationController Error
body: <p>I am trying to make a login page in Flutter, and want to animate before push to the next page. Everything is working fine except when doing(Bad infos in Login so it is calling "failedLoginAnimation" function and after when I entering right infos in my form) it starts to animate at the end of it my App crash and show me but when i enter right infos directly withou doing a mistake before everything works. PS: I'm new to flutter about a month and even more for animations.</p>
  
  <pre><code>    ══╡ EXCEPTION CAUGHT BY ANIMATION LIBRARY ╞═════════════════════════════════════════════════════════
  I/flutter (11398): The following assertion was thrown while notifying listeners for AnimationController:
  I/flutter (11398): Looking up a deactivated widget's ancestor is unsafe.
  I/flutter (11398): At this point the state of the widget's element tree is no longer stable. To safely refer to a
  I/flutter (11398): widget's ancestor in its dispose() method, save a reference to the ancestor by calling
  I/flutter (11398): inheritFromWidgetOfExactType() in the widget's didChangeDependencies() method.
  I/flutter (11398): 
  I/flutter (11398): When the exception was thrown, this was the stack:
  I/flutter (11398): #0      Element._debugCheckStateIsActiveForAncestorLookup.&lt;anonymous closure&gt; (package:flutter/src/widgets/framework.dart:3232:9)
  I/flutter (11398): #1      Element._debugCheckStateIsActiveForAncestorLookup (package:flutter/src/widgets/framework.dart:3241:6)
  I/flutter (11398): #2      Element.ancestorStateOfType (package:flutter/src/widgets/framework.dart:3289:12)
  I/flutter (11398): #3      Navigator.of (package:flutter/src/widgets/navigator.dart:1271:19)
  I/flutter (11398): #4      Navigator.popAndPushNamed (package:flutter/src/widgets/navigator.dart:825:22)
  I/flutter (11398): #5      StaggerAnimationSignIn.build.&lt;anonymous closure&gt; (package:test/premium/pages/login/loginAnimation.dart:146:25)
  I/flutter (11398): #6      _AnimationController&amp;Animation&amp;AnimationEagerListenerMixin&amp;AnimationLocalListenersMixin.notifyListeners (package:flutter/src/animation/listener_helpers.dart:124:19)
  I/flutter (11398): #7      AnimationController._tick (package:flutter/src/animation/animation_controller.dart:693:5)
  I/flutter (11398): #8      Ticker._tick (package:flutter/src/scheduler/ticker.dart:228:5)
  I/flutter (11398): #9      _WidgetsFlutterBinding&amp;BindingBase&amp;GestureBinding&amp;ServicesBinding&amp;SchedulerBinding._invokeFrameCallback (package:flutter/src/scheduler/binding.dart:990:15)
  I/flutter (11398): #10     _WidgetsFlutterBinding&amp;BindingBase&amp;GestureBinding&amp;ServicesBinding&amp;SchedulerBinding.handleBeginFrame.&lt;anonymous closure&gt; (package:flutter/src/scheduler/binding.dart:906:11)
  I/flutter (11398): #11     __InternalLinkedHashMap&amp;_HashVMBase&amp;MapMixin&amp;_LinkedHashMapMixin.forEach (dart:collection/runtime/libcompact_hash.dart:370:8)
  I/flutter (11398): #12     _WidgetsFlutterBinding&amp;BindingBase&amp;GestureBinding&amp;ServicesBinding&amp;SchedulerBinding.handleBeginFrame (package:flutter/src/scheduler/binding.dart:904:17)
  I/flutter (11398): #13     _WidgetsFlutterBinding&amp;BindingBase&amp;GestureBinding&amp;ServicesBinding&amp;SchedulerBinding._handleBeginFrame (package:flutter/src/scheduler/binding.dart:834:5)
  I/flutter (11398): #14     _invoke1 (dart:ui/hooks.dart:159:13)
  I/flutter (11398): #15     _beginFrame (dart:ui/hooks.dart:129:3)
  I/flutter (11398): 
  I/flutter (11398): The AnimationController notifying listeners was:
  I/flutter (11398):   AnimationController#97d39(⏭ 1.000; paused)
  I/flutter (11398): ════════════════════════════════════════════════════════════════════════════════════════════════════
  </code></pre>
  
  <p><strong><em>My LoginPage</em></strong></p>
  
  <pre><code>import 'package:flutter/material.dart';
  import 'loginAnimation.dart';
  import 'freeAccessAnimation.dart';
  import 'package:flutter/foundation.dart';
  import 'package:flutter/animation.dart';
  import 'package:test/premium/tools/jsonTools.dart';
  import 'dart:async';
  import 'package:test/premium/tools/design/color/designColors.dart';
  import './Components/PremiumLink.dart';
  import './Components/ForgotPasswordLink.dart';
  import './Components/Logo.dart';
  import './Components/SignInButton.dart';
  import './Components/FreeAccessButton.dart';
  import 'package:flutter/services.dart';
  import 'package:flutter/scheduler.dart' show timeDilation;
  import 'package:test/premium/tools/internet/checkInternet.dart';
  import 'package:test/premium/pages/tools/alerts.dart';
  import 'package:url_launcher/url_launcher.dart';
  import 'package:test/premium/variables/variablesApp.dart';
  import 'package:test/premium/tools/internet/sendHTTPRequest.dart';
  
  
  class LoginScreen extends StatefulWidget {
    const LoginScreen({Key key}) : super(key: key);
    @override
    LoginScreenState createState() =&gt; new LoginScreenState();
  }
  
  
  class LoginScreenState extends State&lt;LoginScreen&gt;
      with TickerProviderStateMixin {
    static bool hasFinishedLogin;
    static bool hasFailedLogin;
  
    static String userLoginToken ;
    static String tokenFileExist ;
    static String backToLogin;
    static bool isFirstCallAction;
    static bool hasFinishLogAnim;
  
    AnimationController _loginButtonController;
    AnimationController _freeButtonController;
  
    static final usernameController = TextEditingController();
    static final passwordController = TextEditingController();
  
    static var animationStatusLogin = 0;
    static var animationStatusFree = 0;
  
    Future pause(Duration d) =&gt; new Future.delayed(d);
  
    _launchURL(String url) async {
      if (await canLaunch(url)) {
        await launch(url);
      } else {
        throw 'Could not launch $url';
      }
    }
  
    void tokensManagement(){
      if(userLoginToken == null &amp;&amp; tokenFileExist == null &amp;&amp; backToLogin == "true") {
        JTools.deleteFileToken().then((e){
          if(e == "Token has been deleted"){
            setState(() {
              tokenFileExist = 'false';
              userLoginToken = null;
              backToLogin = 'false';
            });
  
          }
        });
  
      }else{
        JTools.readDataToken().then((e){
          String _token = e;
          pause(new Duration(milliseconds: 500)).then((e){
            JTools.tokenFileExist().then((value){
              tokenFileExist = value.toString();
              userLoginToken = _token;
            }).then((b){
              if(_token != null){
                if(userLoginToken.isNotEmpty &amp;&amp; tokenFileExist == 'true'){
                  //TODO: on loading
                  APIToken.token = _token;
                  CheckInternet().checkInternet().then((e){
                    if(e == true){
                          PostHTTP().sendRequestAPI(APIToken.token, 'membership').then((value){
                            if(value['status'] == "200"){
                              String membership = value['membership'];
                              print(membership);
                              if(membership == "138" || membership == "136"){
                                print('User is premium');
                                Navigator.of(context).pushNamed('/main');
                              }else {
                                print("User isn't premium ");
                                JTools.deleteFileToken().then((e) {
                                  if (e == "Token has been deleted") {
                                    setState(() {
                                      tokenFileExist = 'false';
                                      userLoginToken = null;
                                    });
                                    pause(Duration(milliseconds: 1000)).then((e){
                                      Alerts(context: context).alertNotPremium();
                                    });
                                  }
                                });
                              }
                            }else{
                              if(value['status'] == "404"){
                                  setState(() {
                                    tokenFileExist = 'false';
                                    userLoginToken = null;
                                    backToLogin = 'false';
                                  });
                                  pause(Duration(milliseconds: 1000)).then((e){
                                    Alerts(context: context).alertErrorConnectionServer();
                                  });
  
                              }
                              if(value['status'] == "401" || value['status'] == "403")
                              {print("User isn't premium ");
                              JTools.deleteFileToken().then((e) {
                                if (e == "Token has been deleted") {
                                  setState(() {
                                    tokenFileExist = 'false';
                                    userLoginToken = null;
                                    backToLogin = 'false';
                                  });
                                  pause(Duration(milliseconds: 1000)).then((e){
                                    Alerts(context: context).alertNotPremium();
                                  });
                                }
                              });}
                            }
                          });
                    }else{
                      Alerts(context: context).alertInternet();
                      failedLoginAnimation();
                    }
                  });
                }
                else{
                  setState(() {
  
                  });
                }
              }else{
                setState(() {
  
                });
              }
            });
          });
        });
      }
    }
  
    @override
    void initState() {
      super.initState();
      _loginButtonController = new AnimationController(
          duration: new Duration(milliseconds: 3000), vsync: this);
      _freeButtonController = new AnimationController(
          duration: new Duration(milliseconds: 3000), vsync: this);
      tokensManagement();
      animationStatusLogin = 0;
      animationStatusFree = 0;
      print('init LOGIN');
    }
  
    @override
    void dispose() {
      super.dispose();
      _loginButtonController.dispose();
      _freeButtonController.dispose();
    }
  
    Future&lt;Null&gt; _playAnimationLogin() async {
      try {
        await _loginButtonController.forward();
      } on TickerCanceled {}
    }
  
    Future&lt;Null&gt; _playAnimationFree() async {
      try {
        await _freeButtonController.forward();
        await _freeButtonController.reverse();
      } on TickerCanceled {}
    }
  
    Widget formLogin(){
      return new Container(
        margin: new EdgeInsets.symmetric(horizontal: 20.0),
        child: new Column(
          mainAxisAlignment: MainAxisAlignment.spaceEvenly,
          children: &lt;Widget&gt;[
            new Form(
                child: new Column(
                  mainAxisAlignment: MainAxisAlignment.spaceAround,
                  children: &lt;Widget&gt;[
                    new Container(
                      decoration: new BoxDecoration(
                        border: new Border(
                          bottom: new BorderSide(
                            width: 0.5,
                            color: DesignColors.animatedLoginColor,
                          ),
                        ),
                      ),
                      child: new TextFormField(
                        controller: usernameController,
                        keyboardType: TextInputType.emailAddress,
                        style: const TextStyle(
                          color: Colors.white,
                        ),
                        decoration: new InputDecoration(
                          icon: new Icon(
                            Icons.person_outline,
                            color: Colors.white,
                          ),
                          border: InputBorder.none,
                          hintText: "Email/Username",
                          hintStyle: const TextStyle(color: Colors.white, fontSize: 15.0),
                          contentPadding: const EdgeInsets.only(
                              top: 30.0, right: 30.0, bottom: 30.0, left: 5.0),
                        ),
                      ),
                    ),
                    new Container(
                      decoration: new BoxDecoration(
                        border: new Border(
                          bottom: new BorderSide(
                            width: 0.5,
                            color: DesignColors.animatedLoginColor,
                          ),
                        ),
                      ),
                      child: new TextFormField(
                        controller: passwordController,
                        obscureText: true,
                        style: const TextStyle(
                          color: Colors.white,
                        ),
                        decoration: new InputDecoration(
                          icon: new Icon(
                            Icons.lock_outline,
                            color: Colors.white,
                          ),
                          border: InputBorder.none,
                          hintText: "Password",
                          hintStyle: const TextStyle(color: Colors.white, fontSize: 15.0),
                          contentPadding: const EdgeInsets.only(
                              top: 30.0, right: 30.0, bottom: 30.0, left: 5.0),
                        ),
                      ),
                    ),
                  ],
                )),
          ],
        ));
    }
  
    void failedLoginAnimation(){
      setState(() {
        hasFailedLogin = true;
        _playAnimationLogin();
        animationStatusLogin = 0;
      });
    }
  
    Widget logPage(){
      return new WillPopScope(
          onWillPop: () async =&gt; false,
          child: new Scaffold(
              backgroundColor: DesignColors.backgroundColor,
              body: Center(
                child: Theme(
                  data: ThemeData(splashColor: Colors.transparent, textSelectionHandleColor: Colors.blue, highlightColor: Colors.transparent),
                  child:new ListView(
                    shrinkWrap: true,
                    children: &lt;Widget&gt;[
                      new Stack(
                        alignment: AlignmentDirectional.bottomCenter,
                        children: &lt;Widget&gt;[
                          new Column(
                            mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                            children: &lt;Widget&gt;[
                              new Logo(image: DecorationImage(image: ExactAssetImage('assets/images/AppLogo.png'), fit: BoxFit.cover),),
                              formLogin(),
                              new PremiumLink(action: (){_launchURL("someurl");}),
                              new ForgotPasswordLink(action: (){_launchURL("someurl");}),
                            ],
                          ),
                          animationStatusLogin == 0
                              ? new Padding(
                            padding: const EdgeInsets.only(bottom: 160.0),
                            child: new InkWell(
                                onTap: () {
                                  setState(() {
                                    animationStatusLogin = 1;
                                    hasFinishedLogin = false;
                                    hasFinishLogAnim = false;
                                    hasFailedLogin = false;
                                    isFirstCallAction = true;
                                  });
                                  _playAnimationLogin();
                                },
                                child: new SignIn()),
                          )
                              : new StaggerAnimationSignIn( action: (){
                            CheckInternet().checkInternet().then((e){
                              if(e == true){
                                PostHTTP().sendLogin({'username': usernameController.text, 'password': passwordController.text}).then((e){
                                  String responseStatus = e['status'];
                                  if(responseStatus != "200"){
                                    Alerts(context: context).alertFalseInfosLogin();
                                    failedLoginAnimation();
                                  }else{
                                    String token = e['token'];
                                    PostHTTP().sendRequestAPI(token, 'membership').then((value){
                                      if(value['status'] == "200"){
                                        String membership = value['membership'];
                                        print(membership);
                                        if(membership == "138" || membership == "136"){
                                          APIToken.token = token;
                                          JTools.saveLogin(token);
                                          print('User is premium ');
                                          FocusScope.of(context).requestFocus(new FocusNode());
                                          hasFinishedLogin = true;
                                          hasFinishLogAnim = false;
                                          hasFailedLogin = false;
                                          _playAnimationLogin();
                                        }else{
                                          print("User isn't premium ");
                                          Alerts(context: context).alertNotPremium();
                                          failedLoginAnimation();
                                        }
                                      }else{
                                        if(value['status'] == "404"){Alerts(context: context).alertErrorConnectionServer(); failedLoginAnimation();}
                                        if(value['status'] == "401" || value['status'] == "403"){Alerts(context: context).alertNotPremium(); failedLoginAnimation();}
                                      }
                                    });
                                  }
                                });
                              }else{
                                Alerts(context: context).alertInternet();
                                failedLoginAnimation();
                              }
                            });
  
  
                            //Navigator.of(context).popAndPushNamed('/main');
                          },
                              buttonController:
                              _loginButtonController.view
                          ),
  
                          animationStatusFree == 0
                              ? new Padding(
                            padding: const EdgeInsets.only(bottom: 85.0),
                            child: new InkWell(
                                onTap: () {
                                  setState(() {
                                    animationStatusFree = 1;
                                  });
                                  _playAnimationFree();
                                },
                                child: new FreeAccess()),
                          )
                              : new StaggerAnimationFree(
                              buttonController:
                              _freeButtonController.view),
                        ],
                      ),
                    ],
                  ),
                ),
              )
          )
      );
    }
  
    Widget waitingPage(){
      return WillPopScope(child: Scaffold(backgroundColor: DesignColors.backgroundColor.withOpacity(1), body: Center(child: new CircularProgressIndicator(
        value: null,
        strokeWidth: 1.0,
        valueColor: new AlwaysStoppedAnimation&lt;Color&gt;(
            DesignColors.robot1Theme),
      )),), onWillPop:() async =&gt; false);
    }
  
    @override
    Widget build(BuildContext context) {
      timeDilation = 0.4;
      SystemChrome.setSystemUIOverlayStyle(SystemUiOverlayStyle.light);
  
  
      if(userLoginToken == null &amp;&amp; tokenFileExist == 'false'){
        return logPage();
      }
  
      if(userLoginToken == null &amp;&amp; tokenFileExist == null &amp;&amp; backToLogin == "true"){
        //TODO: on loading
        backToLogin ="false";
        tokensManagement();
        return logPage();
      }else if(userLoginToken == null &amp;&amp; tokenFileExist == null){
        //TODO: on loading
        return waitingPage();
      }
  
      if(userLoginToken.isNotEmpty &amp;&amp; tokenFileExist == null){
        //TODO: on loading
        return waitingPage();
      }
  
  
      if(userLoginToken.isEmpty &amp;&amp; tokenFileExist == 'true'){
        return logPage();
      }
  
      return logPage();
    }
  }
  </code></pre>
  
  <p><strong><em>My Animation class</em></strong></p>
  
  <pre><code>import 'package:flutter/material.dart';
  import 'package:test/premium/tools/design/color/designColors.dart';
  import 'login.dart';
  
  class StaggerAnimationSignIn extends StatelessWidget {
    final action;
    StaggerAnimationSignIn({Key key, this.buttonController, @required this.action})
        : buttonSqueezeanimation = new Tween(
            begin: 320.0,
            end: 70.0,
          )
              .animate(
            new CurvedAnimation(
              parent: buttonController,
              curve: new Interval(
                0.0,
                0.175,
              ),
            ),
          ),
          buttomZoomOut = new Tween(
            begin: 70.0,
            end: 5000.0,
          )
              .animate(
            new CurvedAnimation(
              parent: buttonController,
              curve: new Interval(
                0.55,
                0.999,
                curve: Curves.bounceOut,
              ),
            ),
          ),
          containerCircleAnimation = new EdgeInsetsTween(
            begin: const EdgeInsets.only(bottom: 160.0),
            end: const EdgeInsets.only(bottom: 0.0),
          )
              .animate(
            new CurvedAnimation(
              parent: buttonController,
              curve: new Interval(
                0.500,
                0.800,
                curve: Curves.ease,
              ),
            ),
          ),
          super(key: key);
  
    final AnimationController buttonController;
    final Animation&lt;EdgeInsets&gt; containerCircleAnimation;
    final Animation buttonSqueezeanimation;
    final Animation buttomZoomOut;
  
    Widget _buildAnimation(BuildContext context, Widget child) {
      return new Padding(
        padding: buttomZoomOut.value == 80
            ? const EdgeInsets.only(bottom: 160.0)
            : containerCircleAnimation.value,
        child: new InkWell(
            onTap: () {
  
            },
            child: new Hero(
              tag: "fadeLogin",
              child: buttomZoomOut.value &lt;= 300
                  ? new Container(
                      width: buttomZoomOut.value == 70
                          ? buttonSqueezeanimation.value
                          : buttomZoomOut.value,
                      height:
                          buttomZoomOut.value == 70 ? 60.0 : buttomZoomOut.value,
                      alignment: FractionalOffset.center,
                      decoration: new BoxDecoration(
                        color: DesignColors.animatedLoginColor,
                        borderRadius: buttomZoomOut.value &lt; 400
                            ? new BorderRadius.all(const Radius.circular(30.0))
                            : new BorderRadius.all(const Radius.circular(0.0)),
                      ),
                      child: buttonSqueezeanimation.value &gt; 75.0
                          ? new Text(
                              "Sign In",
                              style: new TextStyle(
                                color: Colors.white,
                                fontSize: 20.0,
                                fontWeight: FontWeight.w300,
                                letterSpacing: 0.3,
                              ),
                            )
                          : buttomZoomOut.value &lt; 300.0
                              ? new CircularProgressIndicator(
                                  value: null,
                                  strokeWidth: 1.0,
                                  valueColor: new AlwaysStoppedAnimation&lt;Color&gt;(
                                      Colors.white),
                                )
                              : null)
                  : new Container(
                      width: buttomZoomOut.value,
                      height: buttomZoomOut.value,
                      decoration: new BoxDecoration(
                        shape: buttomZoomOut.value &lt; 500
                            ? BoxShape.circle
                            : BoxShape.rectangle,
                        color: DesignColors.animatedLoginColor,
                      ),
                    ),
            )),
      );
    }
  
  
    @override
    Widget build(BuildContext context) {
        if(LoginScreenState.isFirstCallAction){
          buttonController.addListener(() {
              if (LoginScreenState.isFirstCallAction) {
                print("1");
                LoginScreenState.isFirstCallAction = false;
                action();
              }
  
              if (LoginScreenState.hasFailedLogin) {
                print("3");
                LoginScreenState.hasFailedLogin = false;
                buttonController.reverse();
                LoginScreenState.animationStatusLogin = 0;
              }
  
              if (buttonController.value &gt; 0.2 &amp;&amp;
                  LoginScreenState.hasFinishedLogin == false &amp;&amp;
                  LoginScreenState.hasFailedLogin == false &amp;&amp;
                  LoginScreenState.hasFinishLogAnim == false) {
                print("2");
                buttonController.stop();
              }
  
              if (LoginScreenState.hasFinishedLogin &amp;&amp; !LoginScreenState.hasFailedLogin &amp;&amp; !LoginScreenState.hasFinishLogAnim &amp;&amp; buttonController.value == 1.0) {
                print("4");
                LoginScreenState.hasFinishedLogin = false;
                LoginScreenState.hasFailedLogin = false;
                LoginScreenState.hasFinishLogAnim = true;
                LoginScreenState.animationStatusLogin = 0;
                Navigator.popAndPushNamed(context, "/main");
                return;
            }
          });
  
      }
      return new AnimatedBuilder(
        builder: _buildAnimation,
        animation: buttonController,
      );
    }
  }
  </code></pre>
  
  <p><strong><em>Update</em></strong>:</p>
  
  <p>HI fixed the problems I think, I still need to to do few test but seems that calling  <code>Navigator.popAndPushNamed(context, "/main");</code> in the AnimationClass wasn't a good idea I just changed my Login class in a way that when animation is finished I call <code>Navigator.popAndPushNamed(context, "/main");</code> in my login class. i'll keep updating this post in the incoming days.</p>
  
  <p><strong><em>New start in my build login class</em></strong></p>
  
  <pre><code>      @override
    Widget build(BuildContext context) {
      _loginButtonController.addListener((){
        if(_loginButtonController.isCompleted){
          FocusScope.of(context).requestFocus(new FocusNode());
          Navigator.popAndPushNamed(context, "/main");
        }
      });
  </code></pre>
  
  <p><strong><em>And removed <code>Navigator.popAndPushNamed(context, "/main");</code> and <code>return;</code> in My Animation end call</em></strong></p>