2

Summary

I want to set up entry and exit transitions in flutter. I'm using the go_router package and navigate via context.go. I have set up a working transition on GoRoute. However, setting up a transition on another GoRoute and navigating between the two causes the transition to break. I need help understanding why.


Full

I have two views, ViewA and ViewB like this:

class ViewA extends StatelessWidget {
  const ViewA({super.key});

  @override
  Widget build(BuildContext context) {
    Future.delayed(const Duration(seconds: 5), () {
      context.go("/B");
    });
    return /* ... */;
  }
}

class ViewB extends StatelessWidget {
  const ViewB({super.key});

  @override
  Widget build(BuildContext context) {
    Future.delayed(const Duration(seconds: 5), () {
      context.go("/A");
    });
    return /* ... */;
  }
}

I have set up routes for these views like this:

final routes = GoRouter(routes: <RouteBase>[
  GoRoute(
    path: "/A",
    pageBuilder: (context, state) => CustomTransitionPage(
      child: const ViewA(),
      transitionDuration: const Duration(seconds: 2),
      transitionsBuilder: (context, animation, secondaryAnimation, child) =>
          FadeTransition(
              opacity:
                  CurveTween(curve: Curves.easeInOutCirc).animate(animation),
              child: child),
    ),
  ),
  GoRoute(
    path: "/B",
    pageBuilder: (context, state) => CustomTransitionPage(
        child: const ViewB(),
        transitionDuration: const Duration(seconds: 2),
        transitionsBuilder: (context, animation, secondaryAnimation, child) =>
            FadeTransition(
              opacity:
                  CurveTween(curve: Curves.easeInOutCirc).animate(animation),
              child: child,
            ),
    ),
  ),
]);

However, this results in no transition at all. If I instead change the second route to

GoRoute(
  path: "/B",
  builder: (context, state) => const ViewB(),
),

The animation from "B" -> "A" uses a fade transition as expected whereas "A" -> "B" falls back on the default transition animation.

  • How can I get a fade transition both ways between A and B?
  • Why do the transitions stop working if I define one for each route?
Felix ZY
  • 674
  • 6
  • 14

1 Answers1

1

I believe this has to do with the ValueKey.

If you check out the examples provided in the official repo, you will find this: https://github.com/flutter/packages/blob/main/packages/go_router/example/lib/transition_animations.dart

CustomTransitionPage<void>(
          key: state.pageKey,
          child: const DetailsScreen(),
          transitionDuration: const Duration(milliseconds: 150),
          transitionsBuilder: (BuildContext context,
              Animation<double> animation,
              Animation<double> secondaryAnimation,
              Widget child) {
            // Change the opacity of the screen using a Curve based on the the animation's
            // value
            return FadeTransition(
              opacity:
                  CurveTween(curve: Curves.easeInOut).animate(animation),
              child: child,
            );
          }

Passing in the key state.pageKey seems to fix it for me

My transition:

CustomTransitionPage appContentTransition(
    {required Widget child, required ValueKey<String> pageKey}) {
  return CustomTransitionPage(
      key: pageKey,
      child: child,
      transitionDuration: const Duration(milliseconds: 500),
      transitionsBuilder: (context, animation, secondaryAnimation, child) {
        return SlideTransition(
            position: Tween<Offset>(
              begin: Offset(1.0,
                  0.0),
              end: Offset.zero,
            ).animate(animation),
            child: child);
      });
}
Ben Schreiber
  • 167
  • 1
  • 1
  • 8