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

如何借助Go Router在ShellRoute视图外部显示对话框?

在Flutter Web的go_router中让对话框显示在ShellRoute外部

我正在开发一款使用go_router的Flutter Web应用,需要在ShellRoute视图外部显示对话框。

我编写了如下代码:

ShellRoute(
  builder: (context, state, child) {
    return HomePage(
      child: child,
    ),
  );
  routes: [
    GoRoute(
      path: '/home',
      name: 'home',
      pageBuilder: (_, state) => NoTransitionPage(
        child: const SplashScreen(),
      ),
    ),
    GoRoute(
      path: '/dashboard',
      name: 'dashboard-parent',
      pageBuilder: (_, state) => NoTransitionPage(
        child: DashboardPage.show(
          key: ValueKey(state.params['id'] ?? ''),
        ),
      ),
      routes: [
        GoRoute(
          path: 'details',
          name: 'details',
          pageBuilder: (_, state) => AlertDialog(),
        ),
      ],
    ),
  ],
),
class AlertDialog extends Page {
  @override
  Route createRoute(BuildContext context) => RawDialogRoute(
        pageBuilder: (BuildContext context, Animation<double> animation,
                Animation<double> secondaryAnimation) =>
            Text('TEST'),
        settings: this,
      );
}

目前功能运行正常,但对话框的位置存在问题,我需要将其渲染到主容器之外,期望效果是对话框悬浮在整个页面之上,不受ShellRoute容器的布局限制。


解决方案

问题核心是你把对话框路由设为了/dashboard的子路由,导致它被嵌套在ShellRoute的Navigator中,布局被限制在ShellRoute容器内。可以通过以下方式解决:

1. 调整路由结构,将对话框路由移到ShellRoute同级

把对话框路由从/dashboard的子路由中移出,放到ShellRoute的同级位置,让它由根Navigator处理,自然突破ShellRoute的布局限制:

GoRouter(
  routes: [
    ShellRoute(
      builder: (context, state, child) {
        return HomePage(child: child);
      },
      routes: [
        GoRoute(
          path: '/home',
          name: 'home',
          pageBuilder: (_, state) => NoTransitionPage(child: const SplashScreen()),
        ),
        GoRoute(
          path: '/dashboard',
          name: 'dashboard-parent',
          pageBuilder: (_, state) => NoTransitionPage(
            child: DashboardPage.show(
              key: ValueKey(state.params['id'] ?? ''),
            ),
          ),
        ),
      ],
    ),
    // 将对话框路由放在ShellRoute同级
    GoRoute(
      path: '/dashboard/details',
      name: 'details',
      pageBuilder: (_, state) => AlertDialogPage(),
    ),
  ],
)

2. 优化自定义对话框Page的实现

替换RawDialogRoute为DialogRoute,它会自动处理对话框的全局居中、背景遮罩等标准行为,确保对话框正确悬浮在页面顶层:

class AlertDialogPage extends Page {
  @override
  Route createRoute(BuildContext context) => DialogRoute(
        context: context,
        builder: (context) => const Center(
          child: Material(
            color: Colors.transparent,
            child: Text('TEST'),
          ),
        ),
        settings: this,
      );
}

之后在Dashboard页面中调用context.goNamed('details'),对话框就会显示在ShellRoute视图的外部了。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.31 12:35:31