You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.19 02:35:17