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

使用auto_route ^7.8.3的AutoTabsRouter在Shell路由间导航时Hero动画失效问题

auto_route ^7.8.3的AutoTabsRouter在Shell路由间导航时Hero动画失效问题

问题分析

我之前碰到过类似的场景,Hero动画的核心逻辑是两个Hero组件必须处于同一个Navigator栈的上下文中,而且路由切换得是通过Navigator的push/pop这类标准栈操作触发的。你现在用AutoTabsRouter.of(context).navigate()切换Shell子路由时,本质是在同一个父路由下切换Tab页面,并没有触发Navigator的栈推送动作,Hero框架根本检测不到这种页面切换,自然不会启动动画。再加上你用了嵌套的AutoTabsRouter结构,两个Hero所在的页面可能处于不同的Navigator层级,进一步打乱了Hero的配对逻辑。

可能的解决方案

1. 改用标准Navigator推送跳转

如果FeedBrowseShellRoute不需要作为常驻Tab页,只是从FeedHomeShellRoute跳转过去的临时页面,可以试试用普通的Navigator推送代替AutoTabsRouter的navigate:

InkWell(
  onTap: () {
    Navigator.of(context).push(
      MaterialPageRoute(builder: (_) => FeedBrowseShellView()),
    );
  },
  child: Hero(
    tag: "hero_tag",
    child: // 你的子组件
  ),
)

不过这种方式会脱离AutoTabsRouter的管理,你得根据业务场景判断是否适用。

2. 调整路由结构,统一Navigator层级

把FeedHomeShellRoute和FeedBrowseShellRoute改成同级的普通AutoRoute,不再嵌套在FeedRoute的AutoTabs下,这样它们会共享同一个父Navigator栈,Hero动画就能正常触发。修改后的路由定义大概是这样:

@override
List<AutoRoute> get routes => [
  // 其他路由
  AutoRoute(
    page: MainRoute.page,
    children: [
      AutoRoute(
        initial: true,
        page: FeedRoute.page,
      ),
      AutoRoute(page: FeedBrowseShellRoute.page),
      AutoRoute(page: NewGenerationsRoute.page),
      AutoRoute(page: ProfileRoute.page),
    ],
  ),
  // 其他路由
];

之后在FeedRoute里用context.pushRoute(const FeedBrowseShellRoute())跳转,Hero就能正常工作了。

3. 手动绑定HeroController(备选方案)

如果必须保留当前的嵌套AutoTabsRouter结构,可以尝试给嵌套的AutoTabsRouter手动提供HeroController,确保两个Tab页面的Hero共享同一个控制器:

AutoTabsRouter.tabBar(
  inheritNavigatorObservers: true,
  routes: const [FeedHomeShellRoute(), FeedBrowseShellRoute()],
  builder: (context, child, tabController) {
    return HeroControllerScope(
      controller: HeroController(),
      child: child,
    );
  },
)

不过这种方式不一定能完全解决问题,毕竟Tab切换本质还是没触发Navigator栈变化,Hero可能还是感知不到。

4. 自定义Tab切换的Hero动画(兜底方案)

如果上面的方法都不适用,那就放弃原生Hero,手动实现类似的动画效果:

  • 监听Tab切换事件
  • 获取Hero子组件的全局坐标和尺寸
  • 在切换过程中用Stack+Positioned组件模拟Hero的过渡动画

总结

最稳妥的方案是调整路由结构,让需要Hero动画的两个页面处于同一个Navigator栈中,用标准路由推送触发跳转。如果必须保留Tab结构,手动实现动画可能是更可靠的选择。

备注:内容来源于stack exchange,提问作者TecHaxter

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.20 10:23:10