Flutter 零基础入门(十八):StatefulWidget 生命周期初识
在上一篇中,我们已经掌握了:
- StatefulWidget 与 State 的分工
- setState 如何触发 UI 更新
- 状态驱动 UI 的核心思想
但现在,你一定会开始遇到这样的问题:
👉 数据应该在哪里初始化?
👉 请求接口写在哪?
👉 控制器什么时候释放?
这些问题,都和 生命周期(Lifecycle) 有关。
一、什么是生命周期?
生命周期指的是:
一个页面(State)从创建到销毁的全过程
Flutter 中:
- Widget 会频繁重建
- State 才是真正"长期存在的对象"
二、State 生命周期概览(先有全局印象)
一个典型的 State 生命周期顺序是:
1️⃣ createState
2️⃣ initState
3️⃣ build
4️⃣ setState(多次)
5️⃣ dispose
📌 你现在不需要死记,后面会反复用。
三、createState:创建 State
dart
class Counter extends StatefulWidget {
@override
State<Counter> createState() {
return _CounterState();
}
}
特点:
- 只调用一次
- 负责创建 State 对象
- 很少写逻辑
四、initState:初始化的最佳位置(非常重要)
@override
void initState() {
super.initState();
print('initState');
}
initState 的特点:
- 只调用一次
- State 创建完成后立即执行
- 比 build 更早
- 非常适合做初始化工作
五、initState 能做什么?
✅ 初始化变量
✅ 发起网络请求
✅ 初始化控制器(Animation / TextEditingController)
✅ 订阅事件
📌 原则:
只执行一次的初始化逻辑,放在 initState
六、build:UI 的"说明书"
@override
Widget build(BuildContext context) {
print('build');
return Text('Hello');
}
build 的特点:
- 会执行很多次
- 每次 setState 都会触发
- 只负责描述 UI
❌ 不要在 build 中:
- 请求接口
- 写初始化逻辑
七、setState 在生命周期中的位置
setState(() {
count++;
});
setState 并不是生命周期方法,但它会:
👉 触发 build 重新执行
所以生命周期大致是:
initState → build → setState → build → setState → build ...
八、dispose:资源释放(非常重要)
@override
void dispose() {
print('dispose');
super.dispose();
}
dispose 的特点:
- State 即将被销毁时调用
- 只调用一次
- 用于释放资源
九、为什么一定要 dispose?
如果你使用了:
- Controller
- Stream
- Timer
- 监听器
却没有释放:
👉 内存泄漏 / 异常行为
十、一个完整生命周期示例
class LifeDemo extends StatefulWidget {
@override
State<LifeDemo> createState() => _LifeDemoState();
}
class _LifeDemoState extends State<LifeDemo> {
@override
void initState() {
super.initState();
print('initState');
}
@override
Widget build(BuildContext context) {
print('build');
return ElevatedButton(
onPressed: () {
setState(() {});
},
child: Text('刷新'),
);
}
@override
void dispose() {
print('dispose');
super.dispose();
}
}
运行后你会看到:
- initState 只一次
- build 多次
- dispose 在页面销毁时调用
十一、生命周期的核心职责分工
| 方法 | 责任 |
|---|---|
| initState | 初始化 |
| build | 描述 UI |
| setState | 通知更新 |
| dispose | 清理资源 |
📌 分清职责,是写好 Flutter 的关键。
十二、新手最常见误区
❌ 在 build 中初始化变量
❌ 在 build 中请求接口
❌ 忘记释放控制器
记住:
build 会被反复调用,它不是"开始"的地方
十三、这一篇你真正理解了什么?
你已经能回答:
- 为什么要在 initState 请求数据
- 为什么 setState 会刷新 UI
- 为什么 dispose 一定要写
这意味着:
你开始真正理解 Flutter 的运行机制
十四、总结
本篇你学会了:
- State 生命周期的基本流程
- initState / build / dispose 的职责
- 如何正确放置代码
🔜 下一篇预告
《Flutter 零基础入门(十九):Widget 树、BuildContext 与父子关系》
下一篇我们将学习:
- Widget 树是如何组织的
- BuildContext 到底是什么
- 为什么 context 很重要
- 父子 Widget 如何通信
理解这一篇后:
你会真正"读懂 Flutter Widget 嵌套结构"