Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

flutter: animate transition to named route

When I use Navigator.pushNamed(context, "/someRoute");, there is a minimal animation which slides in the new route from the bottom of the screen (on Android, might look different on iOS).

How can I add a custom animation to this transition?

I found this article, which has some very neat sample code for unnamed routes. They implement their own class which inherits from PageRouteBuilder and can be used like this: Navigator.push(context, SlideRightRoute(page: Screen2())). But a PageRouteBuilder is not a Widget and can't be registered as a route in MaterialApp. So I don't see how to apply this to named routes.

like image 934
lhk Avatar asked Jun 27 '19 13:06

lhk


2 Answers

You need to use onGenerateRoute in your MaterialApp widget.

onGenerateRoute: (settings) {   if (settings.name == "/someRoute") {     return PageRouteBuilder(       settings: settings, // Pass this to make popUntil(), pushNamedAndRemoveUntil(), works       pageBuilder: (_, __, ___) => SomePage(),       transitionsBuilder: (_, a, __, c) => FadeTransition(opacity: a, child: c)     );   }   // Unknown route   return MaterialPageRoute(builder: (_) => UnknownPage()); }, 
like image 69
CopsOnRoad Avatar answered Sep 18 '22 16:09

CopsOnRoad


I found an easy solution (inspired from this code)

First, you need to set a static GlobalKey for MaterialApp and export it

static GlobalKey mtAppKey = GlobalKey();  Widget build(BuildContext context) {   return MaterialApp(     key: MyApp.mtAppKey,     ... 

Also, you need to a custom PageRouteBuilder to handle it

Null-safety disabled

class CustomNamedPageTransition extends PageRouteBuilder {   CustomNamedPageTransition(     GlobalKey materialAppKey,     String routeName, {     Object arguments,   }) : super(           settings: RouteSettings(             arguments: arguments,             name: routeName,           ),           pageBuilder: (             BuildContext context,             Animation<double> animation,             Animation<double> secondaryAnimation,           ) {             assert(materialAppKey.currentWidget != null);             assert(materialAppKey.currentWidget is MaterialApp);             var mtapp = materialAppKey.currentWidget as MaterialApp;             var routes = mtapp.routes;             assert(routes.containsKey(routeName));             return routes[routeName](context);           },           transitionsBuilder: (             BuildContext context,             Animation<double> animation,             Animation<double> secondaryAnimation,             Widget child,           ) =>               FadeTransition(             opacity: animation,             child: child,           ),           transitionDuration: Duration(seconds: 1),         ); } 

Null-safety enabled

class CustomNamedPageTransition extends PageRouteBuilder {   CustomNamedPageTransition(     GlobalKey materialAppKey,     String routeName, {     Object? arguments,   }) : super(           settings: RouteSettings(             arguments: arguments,             name: routeName,           ),           pageBuilder: (             BuildContext context,             Animation<double> animation,             Animation<double> secondaryAnimation,           ) {             assert(materialAppKey.currentWidget != null);             assert(materialAppKey.currentWidget is MaterialApp);             var mtapp = materialAppKey.currentWidget as MaterialApp;             var routes = mtapp.routes;             assert(routes!.containsKey(routeName));             return routes![routeName]!(context);           },           transitionsBuilder: (             BuildContext context,             Animation<double> animation,             Animation<double> secondaryAnimation,             Widget child,           ) =>               FadeTransition(             opacity: animation,             child: child,           ),           transitionDuration: Duration(seconds: 1),         ); } 

Then, you can open your named route with

Navigator.push(   context,   CustomNamedPageTransition(     MyApp.mtAppKey,     MyRoute.routeName,   ), ); 

or

Navigator.pushReplacement(   context,   CustomNamedPageTransition(     MyApp.mtAppKey,     MyRoute.routeName,   ), ); 
like image 20
Furkan Karcıoğlu Avatar answered Sep 19 '22 16:09

Furkan Karcıoğlu