Why does AnimatedSwitcher() not work when nested in an AnimatedBuilder()?

Viewed 450

When I run the following code, on user login the AnimatedBackground() animates successfully, and the page changes from LoginScreen() to HomeScreen(), however there is no animation from the transition.

I suspect it is something to do with nested animations and rebuilds at inopportune times, but it has not been fixed by keys.

class AuthenticationWrapper extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    final User? firebaseuser = context.watch<User?>();
    print("build run with user $firebaseuser");
    return SafeArea(
        child: AnimatedBackground(
      key: Key("salt123value${firebaseuser == null}"),
      animate: firebaseuser == null ? false : true,
      child: AnimatedSwitcher(
          key: Key("animatedswitcher"),
          transitionBuilder: AnimatedSwitcher.defaultTransitionBuilder,
          duration: const Duration(seconds: 4),
          child: firebaseuser == null
              ? LoginScreen(
                  key: Key("login"),
                )
              : HomeScreen(
                  key: Key("home"),
                )),
    ));
  }
}

N.B AnimatedBackground is a custom widget that returns either a CustomPaint(child:child) or a CustomPaint within and AnimatedBuilder

Could it be because AnimatedBckground (animate: bool) returns different widget tree depths depending on the value of animate?

1 Answers

So in the end, wrapping the AnimatedSwticher.defaultLayoutBuilder in my animated widget worked

class AuthenticationWrapper extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    final User? firebaseuser = context.watch<User?>();
    return SafeArea(
        child: AnimatedSwitcher(
            layoutBuilder: (currentChild, previousChildren) =>
                AnimatedBackground(
                  key: ValueKey<String>(firebaseuser?.uid.toString() ?? "none"),
                  animate: firebaseuser != null,
                  child: AnimatedSwitcher.defaultLayoutBuilder(
                      currentChild, previousChildren),
                ),
            duration: const Duration(seconds: 1),
            child: firebaseuser == null ? LoginScreen() : HomeScreen()));
  }
}

So both my animation and AnimatedSwitcher animation ran without affecting one another.

Related