🌟 Flutter 系列专栏(总目录)
本专栏记录从入门到进阶的 Flutter 学习路线,涵盖框架核心机制、路由系统、生命周期、动画、资源管理、网络与原生等内容。
📘 目录结构
01|Flutter 基础
- 01-环境搭建与工具链
- 02-项目结构解析
- 03-Widget 基础与渲染模型
- 04-StatefulWidget 生命周期(含图表)
- 05-BuildContext 深度解析
02|布局系统
- 01-常用布局:Row / Column / Stack / Flex
- 02-尺寸与约束系统(Constraint)
- 03-自适应布局技巧(MediaQuery / LayoutBuilder)
03|路由与导航
- 01-Navigator 1.0 完全解析
- 02-命名路由与参数传递
- 03-Navigator 2.0(声明式)
- 04-GoRouter 深度解析(含刷新、redirect、嵌套路由)
- 05-自定义过渡动画(全体系可用)
04|状态管理
- 01-setState
- 02-InheritedWidget
- 03-Provider
- 04-Riverpod
- 05-Bloc
05|资源系统
- 01-图片资源(Asset / 网络 / 内存)
- 02-Asset 变体(多分辨率资源)
- 03-文本资源加载(rootBundle)
- 04-字体资源与自定义字体
06|网络与存储
- 01-dio 网络请求
- 02-JSON 解析与模型构建
- 03-shared_preferences 本地缓存
- 04-文件与目录管理
07|动画系统
- 01-隐式动画
- 02-显式动画 / AnimationController
- 03-Hero 动画
- 04-CustomPainter 动画
08|原生能力
- 01-MethodChannel 调用原生
- 02-Android 配置
- 03-iOS 配置
🌟 写作风格 🌟
<文章标题>
❗ 本文属于 Flutter 系列第 XX 篇,建议阅读顺序:xx → xx → 当前章节。
📚 本文学习内容
- ✨ 知识点 1
- ✨ 知识点 2
- ✨ 知识点 3
- ✨ ……
🧠 一、什么是 XX?(概念与作用)
简要介绍技术点,包含:
- 产生背景
- 在 Flutter 中的作用
- 为什么需要它
- 它解决了什么问题
🛠 二、XX 的核心用法
对每一个能力逐条拆解:
1️⃣ 基本用法
// 示例代码
📌 解析:
- 代码作用
- 为什么这样写
- 背后机制
2️⃣ 高阶用法 / 可选参数 / 特殊场景
// 示例代码
📌 提示:列出注意事项
🎬 三、运行效果(可选)
如果是 UI 或动画相关,建议加上效果图或描述。
🧩 四、实际项目场景中的使用方式
- 场景 1:xxx
- 场景 2:xxx
- 场景 3:最佳实践
⚠️ 五、常见问题与坑
列出至少 3 个常见问题:
- ⚡ 问题 1:xxxx
解决方式:xxxx - ⚡ 问题 2:xxxx
解决方式:xxxx
❓ 六、这次学习中的疑问记录
你学习过程中真正想问的问题写在这里,例如:
- XX 为什么需要 context?
- Navigator 2.0 与 GoRouter 有什么本质区别?
- AnimationController 为什么必须在 dispose 释放?
📎 八、总结
简明的总结一句话:
本篇的核心是 xx,它解决了 xx,在实际开发中适用于 xx 场景。
🎉 示例文章:Flutter 生命周期
Flutter StatefulWidget 全生命周期(完整图解 + 示例)
❗ 本文属于 Flutter 基础系列第 04 篇。本文将帮你彻底弄懂 StatefulWidget 的生命周期顺序与触发机制。
📚 本文将学习
- StatefulWidget 的完整生命周期流程
- 各生命周期的触发时机
- initState 与 didChangeDependencies 区别
- deactivate 与 dispose 的真实用途
- 容易踩坑的点
🧠 一、StatefulWidget 生命周期是什么?
StatefulWidget 的生命周期描述了:
- widget 创建
- state 挂载
- 依赖更新
- 页面 UI 构建
- 组件移除
- state 销毁
理解生命周期能帮你:
- 正确初始化数据
- 监听/取消监听
- 避免内存泄漏
- 管理动画、控制器、stream
🌀 二、完整生命周期图(建议收藏)
┌──────────────────┐
│ createState() │ ① 生成 State
└─────────┬────────┘
▼
┌──────────────────┐
│ initState() │ ② 初始化(只执行一次)
└─────────┬────────┘
▼
┌──────────────────┐
│ didChangeDependencies() │ ③ 依赖更新
└─────────┬────────┘
▼
┌──────────────────┐
│ build() │ ④ 构建 UI(会多次执行)
└─────────┬────────┘
▼
│ setState(...) → 触发再次 build()
▼
┌──────────────────┐
│ deactivate() │ ⑤ 临时移除(可能返回)
└─────────┬────────┘
▼
┌──────────────────┐
│ dispose() │ ⑥ 永久移除
└──────────────────┘
🔍 三、示例代码(含打印顺序)
class DemoPage extends StatefulWidget {
@override
_DemoPageState createState() => _DemoPageState();
}
class _DemoPageState extends State<DemoPage> {
@override
void initState() {
super.initState();
print("initState");
}
@override
void didChangeDependencies() {
super.didChangeDependencies();
print("didChangeDependencies");
}
@override
Widget build(BuildContext context) {
print("build");
return Scaffold(
body: Center(
child: Text("Lifecycle Demo"),
),
);
}
@override
void deactivate() {
super.deactivate();
print("deactivate");
}
@override
void dispose() {
print("dispose");
super.dispose();
}
}
🧩 四、重点详解
1️⃣ initState(只执行一次)
- 初始化数据
- 创建 AnimationController
- 创建 Stream / Timer
2️⃣ didChangeDependencies(依赖变化触发)
当以下情况触发:
- InheritedWidget 更新
- Localizations 更新
- MediaQuery 改变(屏幕旋转)
💡 即使你没有在 initState 做任何事,它仍然会执行一次。
3️⃣ build(频率最高)
触发场景:
- 第一次渲染
- setState
- 父组件改变
- 屏幕旋转
- MediaQuery 变化
4️⃣ deactivate
组件暂时从 widget tree 移除,但可能会再次挂回去(例如 TabView 切换)。
5️⃣ dispose
组件彻底销毁,必须释放资源:
- AnimationController.dispose
- ScrollController.dispose
- StreamSubscription.cancel
⚠️ 五、常见问题
❓ didChangeDependencies 一定会执行吗?
✔ 会,无论你是否在 initState 初始化内容。
📎 六、总结
StatefulWidget 的生命周期顺序固定:init → dependencies → build → deactivate → dispose。
理解顺序有助于管理资源、避免内存泄漏与异常。