3.5 KiB
3.5 KiB
【Demo】GridView 网格布局(三种构造)
源文件:
lib/pages/demo/grid_demo.dart| 分类:基础布局 一句话:九宫格/相册/功能宫格都靠它,三种构造方式一次看懂。
一、这个 Demo 解决什么问题
"功能宫格(4×2 图标)"、"相册缩略图(3 列)"、"课程卡片墙"这类多列等宽网格布局。 GridView 就是 Flutter 的网格容器,支持懒加载,大量数据不卡。
二、怎么运行 / 演示内容
runApp(const MaterialApp(home: GridDemoPage()));
一屏并排演示三种构造:
GridView.count:固定 3 列,写死 children;GridView.builder:4 列,itemCount: 100懒加载;GridView.extent:每项最多 80 宽,屏幕越宽列数自动变多。
三、核心知识点(新手向)
1. 三个常用构造怎么选
| 构造 | 特点 | 适用 |
|---|---|---|
GridView.count |
固定列数,children 一次性全创建 | 少量固定网格(< 30) |
GridView.builder |
懒加载,itemCount + itemBuilder |
大量数据首选(100+ 条) |
GridView.extent |
按"每项最大宽度"自适应列数 | 响应式场景(Pad 变列数) |
2. 核心参数
GridView.builder(
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 4, // 列数
mainAxisSpacing: 8.w, // 主轴(上下行)间距
crossAxisSpacing: 8.w, // 交叉轴(左右列)间距
childAspectRatio: 1, // 每项 宽:高 比例,默认 1 = 正方形
),
itemCount: 100,
itemBuilder: (context, index) => _GridItem(index: index),
)
3. 重点记忆:GridView 的本质
GridView = CustomScrollView + 1 个 SliverGrid(框架内部自动包的简化套餐)。
- 页面只有网格 →
GridView.builder直接用; - 页面要混排(折叠 AppBar + 网格 + 列表)→ 用
CustomScrollView + slivers(见 sliver_demo.md)。
四、关键代码剖析
// Demo3:extent 自适应列数
GridView.extent(
maxCrossAxisExtent: 80.w, // 每项最多 80 宽 → 屏幕宽时自动多列
mainAxisSpacing: 8.w,
crossAxisSpacing: 8.w,
childAspectRatio: 1,
children: [for (int i = 0; i < 12; i++) _GridItem(index: i)],
)
响应式网格更精细的做法见 responsive_demo.md: 用
LayoutBuilder拿真实宽度,(width / 280).floor().clamp(1, 4)算列数。
五、踩坑记录
- GridView 放 Column 里必须 SizedBox 定高或 Expanded,否则报
Vertical viewport was given unbounded height(和 ListView 同一个坑)。 childAspectRatio太小(如 0.5)时,格子内文字会被挤压溢出 —— 调大比例或缩小字号。- 本页外层
SingleChildScrollView只是"展示台"(为了并排演示 3 种构造), 真实网格页别学这个外层 —— 网格自己就能滚。 - 想"网格 + 下拉刷新",用
RefreshIndicator包 GridView(写法同 list_demo.md 的列表刷新)。
六、扩展思考
SliverGridDelegateWithMaxCrossAxisExtent:同 extent 效果的另一种 delegate 写法;- 相册九宫格真实案例见 note_picker_demo.md:
GridView + "加号格" + 右上角删除角标(Stack 组合),多一格用
itemCount: _images.length + 1; - 性能提示:builder 系列(builder/extent.builder)是懒加载,
count不是 —— 大列表务必 builder。