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

如何用go_router实现Flutter网页滚动?解决页面重复构建问题

问题解决:GoRouter ShellRoute滚动失效与页面重复构建

一、解决页面垂直滚动问题

问题根源

  • 多层嵌套Scaffold(ShellRoute已包含Scaffold,HomePage又额外嵌套)导致布局约束冲突,引发渲染异常。
  • 可滚动组件未正确包裹需要滚动的内容区域,无法触发垂直滚动。

修复步骤

  1. 移除HomePage中的Scaffold,直接返回内容组件,避免嵌套冲突。
  2. 在ShellRoute的Expanded组件内,用SingleChildScrollView包裹子页面内容,确保头部(Banner和导航栏)固定,下方区域可滚动。

修改后的ShellRoute代码

ShellRoute(
  builder: (context, state, child) {
    return Scaffold(
      body: Padding(
        padding: EdgeInsets.symmetric(horizontal: 200),
        child: Column(
          children: [
            Image.asset('images/Banner.png'), // 头部图片
            Container( // 导航栏
              color: Colors.blue,
              height: 100,
            ),
            // 用SingleChildScrollView包裹子页面,实现滚动
            Expanded(
              child: SingleChildScrollView(
                child: child,
              ),
            ),
          ],
        ),
      ),
    );
  },
  routes: [
    GoRoute(
      path: "/",
      builder: (context, state) {
        return const HomePage();
      },
    ),
  ],
)

修改后的HomePage代码

class HomePage extends StatelessWidget {
  const HomePage({super.key});

  @override
  Widget build(BuildContext context) {
    print('hit');
    return Column(
      children: [
        Container(height: 200, color: Colors.purple),
        Container(height: 300, color: Colors.green),
        Container(height: 400, color: Colors.red),
      ],
    );
  }
}

二、解决HomePage重复构建问题

问题根源

  • GoRouter初始化或热重启时,可能触发多次路由重建;无状态组件未用const修饰时,每次都会创建新实例,导致build方法重复调用。

修复方案

方案1:使用const构造函数(适用于无状态组件)

给HomePage添加const构造函数,并在路由builder中使用const HomePage(),Flutter会复用同一实例,减少不必要的构建:

class HomePage extends StatelessWidget {
  const HomePage({super.key}); // 添加const构造函数

  @override
  Widget build(BuildContext context) {
    print('hit');
    return Column(/* 内容不变 */);
  }
}

// 路由配置中使用const实例
GoRoute(
  path: "/",
  builder: (context, state) {
    return const HomePage();
  },
),

方案2:StatefulWidget+AutomaticKeepAliveClientMixin(适用于需加载数据的页面)

如果HomePage需要执行API请求等异步操作,改为StatefulWidget,在initState中处理网络请求,同时用AutomaticKeepAliveClientMixin保持页面状态,避免重复构建:

class HomePage extends StatefulWidget {
  const HomePage({super.key});

  @override
  State<HomePage> createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> with AutomaticKeepAliveClientMixin {
  @override
  bool get wantKeepAlive => true; // 开启状态保持

  @override
  void initState() {
    super.initState();
    // 在此处执行API请求,仅触发一次
    print('加载API数据');
  }

  @override
  Widget build(BuildContext context) {
    super.build(context); // 必须调用super.build
    print('hit');
    return Column(/* 内容不变 */);
  }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 19:22:51