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

Flutter:如何让含PageView、ListView、GridView的Column整体垂直滚动

解决方案:让Column包含的组件实现整体垂直滚动

问题分析

你遇到的内容消失问题,核心原因是:

  • SingleChildScrollView 的父级不能用 Expanded,且其子组件中不能存在依赖父组件尺寸的 Expanded(SingleChildScrollView 本身没有固定高度,Expanded 无法获取可用空间)
  • GridView 未设置 shrinkWrap: true,即使禁用了滚动,它依然会试图占满剩余空间,导致布局冲突

关键修改点

  1. 移除 SingleChildScrollView 外层的 Expanded,直接将 SingleChildScrollView 作为 body 的子组件
  2. 去掉 PageView 外层多余的 Expanded(已经用 SizedBox 固定了高度)
  3. 给 GridView 添加两个属性:
    • shrinkWrap: true:让GridView根据子项总高度收缩自身尺寸
    • physics: NeverScrollableScrollPhysics():禁用GridView的独立垂直滚动
  4. 确保所有需要固定高度的组件(如PageView、水平ListView)都通过 SizedBox 明确设置高度,避免布局歧义

修改后的完整代码

import 'package:flutter/material.dart';
import 'package:smooth_page_indicator/smooth_page_indicator.dart';
import 'listing.dart';

class TrackPage extends StatelessWidget {
  final _controller = PageController(initialPage: 0);

  TrackPage({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: const Color.fromARGB(255, 224, 174, 113),
      appBar: AppBar(
        backgroundColor: Colors.transparent,
        elevation: 0,
        leading: BackButton(
          color: Colors.black,
          onPressed: () {
            Navigator.pop(context);
          },
        ),
        centerTitle: true,
        title: const Text('Vouchers', style: TextStyle(color: Colors.black)),
      ),
      body: SingleChildScrollView(
        child: Column(
          children: [
            Padding(
              padding: const EdgeInsets.fromLTRB(20, 0, 20, 20),
              child: SizedBox(
                height: 200,
                // 移除多余的Expanded
                child: PageView(
                  controller: _controller,
                  children: [
                    Container(
                      color: const Color(0xFFE2D240),
                      child: Row(
                        mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                        children: [
                          Image.asset('lib/images/x.png', width: 150),
                          Column(
                            mainAxisAlignment: MainAxisAlignment.center,
                            children: const [
                              Center(child: Text('35% Off')),
                              SizedBox(height: 20),
                              Text('Super Cool')
                            ],
                          ),
                        ],
                      ),
                    ),
                    Container(
                      color: Colors.red,
                      child: Row(
                        mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                        children: [
                          Image.asset('lib/images/x.png', width: 150),
                          Column(
                            mainAxisAlignment: MainAxisAlignment.center,
                            children: const [
                              Center(child: Text('30% Off')),
                              SizedBox(height: 20),
                              Text('Super Cool')
                            ],
                          ),
                        ],
                      ),
                    ),
                    Container(
                      color: Colors.green,
                      child: Row(
                        mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                        children: [
                          Image.asset('lib/images/x.png', width: 150),
                          Column(
                            mainAxisAlignment: MainAxisAlignment.center,
                            children: const [
                              Center(child: Text('25% Off')),
                              SizedBox(height: 20),
                              Text('Super Cool')
                            ],
                          ),
                        ],
                      ),
                    ),
                  ],
                ),
              ),
            ),
            SmoothPageIndicator(
              controller: _controller,
              count: 3,
              effect: const WormEffect(
                dotColor: Colors.blueGrey,
                activeDotColor: Colors.blue,
                dotWidth: 8,
                dotHeight: 8,
              ),
            ),
            const SizedBox(height: 20),
            // Tags in list view
            SizedBox(
              height: 50,
              child: ListView(
                scrollDirection: Axis.horizontal,
                children: const [
                  Listing(text: 'Test'),
                  Listing(text: 'Test'),
                  Listing(text: 'Test'),
                  Listing(text: 'Test', onTap: null),
                  Listing(text: 'Test'),
                  Listing(text: 'Test'),
                ],
              ),
            ),
            const SizedBox(height: 20),
            // 修改GridView的配置
            GridView.builder(
              shrinkWrap: true,
              physics: const NeverScrollableScrollPhysics(),
              itemCount: 6,
              padding: const EdgeInsets.symmetric(horizontal: 5),
              gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
                crossAxisCount: 2,
                mainAxisSpacing: 15,
                crossAxisSpacing: 15,
              ),
              itemBuilder: (context, index) {
                return Container(
                  color: Colors.white,
                );
              },
            ),
            // Gallery pictures in grid view
            Image.asset('lib/images/x.png', width: 20),
          ],
        ),
      ),
      bottomNavigationBar: BottomNavigationBar(
        currentIndex: 0,
        items: const [
          BottomNavigationBarItem(icon: Icon(Icons.home), label: 'Test'),
          BottomNavigationBarItem(icon: Icon(Icons.home), label: 'Test'),
          BottomNavigationBarItem(icon: Icon(Icons.home), label: 'Test'),
        ],
      ),
    );
  }
}

验证效果

修改后:

  • 整个页面可以垂直滚动,PageView和水平ListView保留各自的水平滚动功能
  • GridView不再独立滚动,会随页面整体垂直移动
  • 所有内容正常显示,没有布局错误

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 23:19:51