flutter架 构项目基础

This commit is contained in:
崔宝新
2026-09-04 15:22:20 +08:00
parent 70967229d0
commit 0c5aee59c0
265 changed files with 35484 additions and 0 deletions
+92
View File
@@ -0,0 +1,92 @@
# 【Demo】GridView 网格布局(三种构造)
> 源文件:`lib/pages/demo/grid_demo.dart` | 分类:基础布局
> 一句话:九宫格/相册/功能宫格都靠它,三种构造方式一次看懂。
---
## 一、这个 Demo 解决什么问题
"功能宫格(4×2 图标)"、"相册缩略图(3 列)"、"课程卡片墙"这类**多列等宽网格**布局。
GridView 就是 Flutter 的网格容器,支持**懒加载**,大量数据不卡。
---
## 二、怎么运行 / 演示内容
```dart
runApp(const MaterialApp(home: GridDemoPage()));
```
一屏并排演示三种构造:
1. `GridView.count`:固定 3 列,写死 children;
2. `GridView.builder`:4 列,`itemCount: 100` 懒加载;
3. `GridView.extent`:每项最多 80 宽,**屏幕越宽列数自动变多**。
---
## 三、核心知识点(新手向)
### 1. 三个常用构造怎么选
| 构造 | 特点 | 适用 |
|---|---|---|
| `GridView.count` | 固定列数,children 一次性全创建 | 少量固定网格(< 30) |
| `GridView.builder` | 懒加载,`itemCount` + `itemBuilder` | **大量数据首选**(100+ 条) |
| `GridView.extent` | 按"每项最大宽度"自适应列数 | 响应式场景(Pad 变列数) |
### 2. 核心参数
```dart
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](sliver_demo.md))。
---
## 四、关键代码剖析
```dart
// 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](responsive_demo.md):
> 用 `LayoutBuilder` 拿真实宽度,`(width / 280).floor().clamp(1, 4)` 算列数。
---
## 五、踩坑记录
1. **GridView 放 Column 里必须 SizedBox 定高或 Expanded**,否则报
`Vertical viewport was given unbounded height`(和 ListView 同一个坑)。
2. **`childAspectRatio` 太小(如 0.5)时,格子内文字会被挤压溢出** —— 调大比例或缩小字号。
3. 本页外层 `SingleChildScrollView` 只是"展示台"(为了并排演示 3 种构造),
真实网格页**别学这个外层** —— 网格自己就能滚。
4. 想"网格 + 下拉刷新",用 `RefreshIndicator` 包 GridView(写法同 [list_demo.md](list_demo.md) 的列表刷新)。
---
## 六、扩展思考
- **`SliverGridDelegateWithMaxCrossAxisExtent`**:同 extent 效果的另一种 delegate 写法;
- 相册九宫格真实案例见 [note_picker_demo.md](note_picker_demo.md):
GridView + "加号格" + 右上角删除角标(Stack 组合),多一格用 `itemCount: _images.length + 1`;
- 性能提示:builder 系列(builder/extent.builder)是懒加载,`count` 不是 —— 大列表务必 builder。