Flutter 零基础入门(十八):StatefulWidget 生命周期初识

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 嵌套结构"

相关推荐
似水明俊德26 分钟前
02-C#.Net-反射-面试题
开发语言·面试·职场和发展·c#·.net
漫随流水37 分钟前
旅游推荐系统(view.py)
前端·数据库·python·旅游
Thera7771 小时前
C++ 高性能时间轮定时器:从单例设计到 Linux timerfd 深度优化
linux·开发语言·c++
踩着两条虫2 小时前
VTJ.PRO 核心架构全公开!从设计稿到代码,揭秘AI智能体如何“听懂人话”
前端·vue.js·ai编程
炘爚2 小时前
C语言(文件操作)
c语言·开发语言
阿蒙Amon2 小时前
C#常用类库-详解SerialPort
开发语言·c#
凸头2 小时前
CompletableFuture 与 Future 对比与实战示例
java·开发语言
wuqingshun3141592 小时前
线程安全需要保证几个基本特征
java·开发语言·jvm
Moksha2623 小时前
5G、VoNR基本概念
开发语言·5g·php
jzlhll1233 小时前
kotlin Flow first() last()总结
开发语言·前端·kotlin