Flutter中仅在特定页面间设置导航动画的实现方法
实现特定页面间的专属导航动画
要在PageA→PageC、PageB→PageC分别设置不同的导航动画,核心是在路由切换时识别来源页面,再根据来源-目标的组合选择对应动画,具体实现如下:
方法一:跳转时传入来源页标识(推荐)
在跳转至PageC时,通过arguments参数携带来源页的标记:
- PageA中跳转:
Navigator.pushNamed(context, '/pageC', arguments: {'from': 'PageA'});
- PageB中跳转:
Navigator.pushNamed(context, '/pageC', arguments: {'from': 'PageB'});
然后在onGenerateRoute中解析参数,根据来源页选择动画:
Route<dynamic> onGenerateRoute(RouteSettings settings) { switch (settings.name) { case '/pageC': final args = settings.arguments as Map<String, String>?; final fromPage = args?['from']; // PageA → PageC 自定义动画(左滑入) if (fromPage == 'PageA') { return PageRouteBuilder( pageBuilder: (context, animation, secondaryAnimation) => PageC(), transitionsBuilder: (context, animation, secondaryAnimation, child) { const begin = Offset(-1.0, 0.0); const end = Offset.zero; const curve = Curves.ease; final tween = Tween(begin: begin, end: end).chain(CurveTween(curve: curve)); return SlideTransition(position: animation.drive(tween), child: child); }, ); } // PageB → PageC 自定义动画(底部滑入) else if (fromPage == 'PageB') { return PageRouteBuilder( pageBuilder: (context, animation, secondaryAnimation) => PageC(), transitionsBuilder: (context, animation, secondaryAnimation, child) { const begin = Offset(0.0, 1.0); const end = Offset.zero; const curve = Curves.easeOut; final tween = Tween(begin: begin, end: end).chain(CurveTween(curve: curve)); return SlideTransition(position: animation.drive(tween), child: child); }, ); } // 默认动画(非A/B跳转至C时使用) return MaterialPageRoute(builder: (_) => PageC()); // 其他页面路由配置 default: return MaterialPageRoute(builder: (_) => const Scaffold(body: Center(child: Text('未知页面')))); } }
方法二:通过路由历史栈获取来源页
如果不想传递参数,也可以通过当前路由的历史栈获取上一页的路由名称,但这种方式可靠性稍差(比如直接打开PageC时无历史记录):
Route<dynamic> onGenerateRoute(RouteSettings settings) { if (settings.name == '/pageC') { final previousRouteName = ModalRoute.of(navigatorKey.currentContext!)?.settings.name; if (previousRouteName == '/pageA') { // 加载PageA→PageC的动画 } else if (previousRouteName == '/pageB') { // 加载PageB→PageC的动画 } return MaterialPageRoute(builder: (_) => PageC()); } // 其他路由逻辑... }
注:使用此方法需要提前初始化
GlobalKey<NavigatorState>来获取上下文。
内容的提问来源于stack exchange,提问作者Henrique da Silva Cardoso
相关产品推荐
相关产品推荐

