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
+114
View File
@@ -0,0 +1,114 @@
# 【Demo】CustomScrollView + Sliver 混排布局
> 源文件:`lib/pages/demo/sliver_demo.dart` | 分类:基础布局
> 一句话:折叠 AppBar + 网格 + 长列表"整页只滚一次",靠 Sliver 碎片拼装。
---
## 一、这个 Demo 解决什么问题
页面要同时包含"可折叠的大图 AppBar + 网格区块 + 长列表区块"时:
- **ListView 不能嵌套 ListView/GridView**(同向滚动会冲突,控制权打架);
- 正解是 `CustomScrollView`:把所有区块变成 Sliver"碎片"拼在一起,**共用一个滚动控制器,整页只滚一次**。
---
## 二、怎么运行 / 演示内容
```dart
runApp(const MaterialApp(home: SliverDemoPage()));
```
页面从上到下:折叠大图 AppBar → 网格标题 → 12 格网格 → 列表标题 → 50 条列表,
下滑时 AppBar 收起固定,其余内容连续滚动。
---
## 三、核心知识点(新手向)
### 1. Sliver 是什么
Sliver = "碎片"。`CustomScrollView` 把多个 sliver 拼成一个统一滚动视图。
### 2. 常用 sliver 对照表
| Sliver | 作用 | 对应普通组件 |
|---|---|---|
| `SliverAppBar` | 可折叠/固定的 AppBar | AppBar |
| `SliverToBoxAdapter` | 把普通组件(文字/卡片)塞进滚动流 | 任意 Widget |
| `SliverGrid.builder` | 网格区块(懒加载) | GridView |
| `SliverList.builder` | 列表区块(懒加载) | ListView.builder |
| `SliverPadding` | 给某个 sliver 加内边距 | Padding |
### 3. 核心结构
```dart
CustomScrollView(
slivers: [
SliverAppBar( // ① 折叠 AppBar
expandedHeight: 180.h,
pinned: true, // 滚动时固定在顶部
flexibleSpace: FlexibleSpaceBar(
title: Text('Sliver 系列 Demo'),
background: DecoratedBox(...), // 展开时的大图
),
),
SliverToBoxAdapter( // ② 普通文字标题
child: Padding(...Text('网格区块(SliverGrid)')),
),
SliverPadding( // ③ 网格区块(带外边距)
padding: EdgeInsets.all(16.w),
sliver: SliverGrid.builder(...),
),
SliverList.builder( // ④ 列表区块
itemCount: 50,
itemBuilder: ...,
),
],
)
```
### 4. 判断口诀(什么时候用 Sliver)
- 页面是"**一个网格**"或"**一个列表**" → `GridView` / `ListView` 更简单;
- 页面是"**折叠头 + 网格 + 长列表**"混排 → `CustomScrollView + slivers`。
---
## 四、关键代码剖析
### 折叠 AppBar(本页的灵魂)
```dart
SliverAppBar(
expandedHeight: 180.h, // 展开时高度(大图区域)
pinned: true, // 上滑时缩成一条标题栏并固定在顶部
backgroundColor: Color(0xFF3B82F6),
flexibleSpace: FlexibleSpaceBar(
title: Text('Sliver 系列 Demo'),
centerTitle: true,
background: DecoratedBox( // 展开时显示的大图(这里是渐变)
decoration: BoxDecoration(
gradient: LinearGradient(
colors: [Color(0xFF3B82F6), Color(0xFF8E6FE8)],
),
),
),
),
)
```
---
## 五、踩坑记录
1. **slivers 里的组件必须是 Sliver 家族**,普通 Widget(如 Container)直接放会报类型错误——
要用 `SliverToBoxAdapter` 包一层;
2. **同向嵌套滚动是禁区**:CustomScrollView 里不能再放 ListView/GridView;
3. `SliverAppBar` 不设 `pinned` 时,上滑后 AppBar 会完全滚出屏幕(floating 可以浮回)——按产品需求选;
4. Sliver 的懒加载与 GridView/ListView 相同:builder 系列才懒加载。
---
## 六、扩展思考
- **Sliver 与 GridView 的本质关系**(重点记忆):
`GridView = CustomScrollView + 1 个 SliverGrid`,两者都是"单个滚动 + 懒加载",区别只在混排能力;
- 进阶 Sliver:`SliverPersistentHeader`(吸顶 Tab)、`SliverAnimatedList`(增删动画列表)、`SliverAppBar` 的 `snap` 模式;
- 电商首页 = Sliver 混排的教科书场景:搜索栏吸顶 + 轮播 + 宫格 + 瀑布流商品;
- 对照 [responsive_demo.md](responsive_demo.md):Sliver 解决"滚动结构",响应式解决"不同宽度下的结构",两者可叠加。