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

使用animations库的OpenContainer时如何修改go_router的location?

解决OpenContainer跳转时更新GoRouter router.location的方案

方案一:将OpenContainer过渡集成到GoRouter页面转场(推荐)

让GoRouter完全管理路由,自动同步router.location,同时保留OpenContainer的过渡效果。

  1. 配置GoRouter路由,添加自定义过渡
    修改GoRouter配置,为目标路由设置pageBuilder,使用和OpenContainer对应的过渡动画:
final GoRouter router = GoRouter(
  routes: [
    GoRoute(
      path: '/',
      builder: (context, state) => const HomePage(),
      routes: [
        GoRoute(
          path: 'categories',
          name: 'categories',
          pageBuilder: (context, state) {
            return CustomTransitionPage(
              key: state.pageKey,
              child: const CategoryPage(),
              // 对应ContainerTransitionType.fade过渡
              transitionsBuilder: (context, animation, secondaryAnimation, child) {
                return FadeTransition(
                  opacity: CurvedAnimation(
                    parent: animation,
                    curve: Curves.easeInOut,
                  ),
                  child: child,
                );
              },
              transitionDuration: const Duration(milliseconds: 300), // 和OpenContainer默认时长一致
            );
          },
        ),
      ],
    ),
  ],
);
  1. 修改OpenContainerWrapper调用逻辑
    不再依赖OpenContainer的路由跳转,直接用GoRouter导航,同时保留OpenContainer的closed状态交互:
// 调用处代码修改
return GestureDetector(
  onTap: () {
    // GoRouter跳转自动更新location
    GoRouter.of(context).pushNamed('categories');
  },
  child: WidgetWithBackground(
    backgroundColor: textColor.withOpacity(0.25),
    // 原有的UI代码
  ),
);

如果需要保留OpenContainer的点击缩放动画,可继续用OpenContainer但禁用其路由跳转:

return OpenContainer<bool>(
  tappable: false,
  closedBuilder: (context, _) {
    return GestureDetector(
      onTap: () {
        GoRouter.of(context).pushNamed('categories');
      },
      child: WidgetWithBackground(
        backgroundColor: textColor.withOpacity(0.25),
        // 原有的UI代码
      ),
    );
  },
  openBuilder: (context, _) => const SizedBox.shrink(), // 无需实际跳转路由
);

方案二:手动同步GoRouter location(不推荐,应急使用)

继续使用OpenContainer原生路由跳转,手动修改GoRouter的location,需注意路由栈同步问题:

修改_OpenContainerWrapper,在打开和关闭回调中同步location:

class _OpenContainerWrapper extends StatelessWidget {
  const _OpenContainerWrapper({
    required this.closedBuilder,
    required this.transitionType,
    required this.onClosed,
    required this.page,
    this.routeSettings,
    this.borderRadius = 4,
  });

  final CloseContainerBuilder closedBuilder;
  final ContainerTransitionType transitionType;
  final ClosedCallback<bool?> onClosed;
  final Widget page;
  final RouteSettings? routeSettings;
  final double borderRadius;

  @override
  Widget build(BuildContext context) {
    final GoRouter router = GoRouter.of(context);
    String? previousLocation;

    return OpenContainer<bool>(
      closedElevation: 0,
      closedColor: Colors.transparent,
      middleColor: Colors.transparent,
      openColor: Colors.transparent,
      routeSettings: routeSettings,
      closedShape: RoundedRectangleBorder(
        borderRadius: BorderRadius.all(Radius.circular(borderRadius)),
      ),
      transitionType: transitionType,
      onOpen: () {
        previousLocation = router.location;
        if (routeSettings?.name != null) {
          router.replaceNamed(routeSettings!.name!);
        }
      },
      openBuilder: (context, _) => page,
      onClosed: (result) {
        if (previousLocation != null) {
          router.replace(previousLocation!);
        }
        onClosed(result);
      },
      tappable: false,
      closedBuilder: closedBuilder,
    );
  }
}

⚠️ 注意:该方案可能导致GoRouter路由栈与Navigator栈不一致,引发返回按钮行为异常,仅建议在无法重构路由逻辑时临时使用。


内容的提问来源于stack exchange,提问作者mirkancal

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 03:35:28