每日一题 Flutter#12 | StatefulWidget 从诞生到状态类build 的流程


最近在着手开发我的 《匠心星问》 ,它定位是一款 题库 应用,将集题目浏览、发布、解答、做题为一体。打算第一步先以 Flutter 为核心,准备题库资源。于是诞生《每日一题》 系列,准备精心设计一些 Flutter 的问题与解答,作为题库的养料。本文的焦点是探讨:

说说 StatefulWidget 从诞生到状态类 build 的流程

在 Flutter 中,build 函数是自定义组件最核心的部分,负责构建和组合 UI 界面。但它的触发是 Flutter 框架内部的行为,理解 build 函数的触发时机,不仅有助于我们更清晰地把握界面构建流程,也能够加深对 Flutter 框架运行逻辑的理解。

-

1.调试案例介绍

这里以最简单的颜色展示为案例来介绍,如下所示:定义 MyApp 作为入口,其中展示 ColorAlphaChangeableView 组件 。我们将专注于 ColorAlphaView 从诞生到对应状态类 build 的流程:

dart 复制代码
void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return ColorAlphaView(color: Colors.blue);
  }
}

ColorAlphaView 可以接收一个颜色值,界面上展示这个颜色。在点击时, 该颜色的透明度在 0.5 和 1 切换,如下所示:

dart 复制代码
class ColorAlphaView extends StatefulWidget {
  final Color color;

  const ColorAlphaView({super.key, required this.color});

  @override
  State<ColorAlphaView> createState() => _ColorAlphaViewState();
}

class _ColorAlphaViewState extends State<ColorAlphaView> {
  late Color _activeColor = widget.color;

  void toggleColor() {
    if (_activeColor.a == 1) {
      _activeColor = widget.color.withValues(alpha: 0.5);
    } else {
      _activeColor = widget.color;
    }
    setState(() {});
  }

  @override
  Widget build(BuildContext context) {
    return GestureDetector(
      onTap: toggleColor,
      child: ColoredBox(color: _activeColor),
    );
  }
}

1. StatefulWidget 对象的创建

首先把断点放在 ColorAlphaView 的构造函数上,可以看到对象创建时的方法栈的调用情况。结构如下所示:

它是在 MyApp#build 中被触发的,也就是说:父级组件在构建 (build) 的过程中会实例化子组件。


2. State 状态类对象的创建

将断点放在 ColorAlphaView#createState 上,可以看到 State 对象创建的时机。

从方法栈中可以看出:状态里是在 StatefulElement 对象实例化中被创建的。StatefulElement 的实例化关键在 Element.inflateWidget 方法中。

此时元素是 MyApp 对应的 StatelessElement,当它要更新子节点时。子节点对应的组件(比如这里的 ColorAlphaView) 就会触发 createElement, 创建对应的 StatefulElement 对象。


3. State#build 的触发时机

在 ColorAlphaView 创建完 StatefulElement 元素对象之后,该元素会紧接着触发 mount 方法。从方法栈中可以看出,元素挂载会触发首次 build 构建逻辑:

StatelessElement 的 build 方法中,会触发其持有的 state 对象的 build 回调。并将自身作为构建上下文作为函数入参。

到这里,大家可以结合一下 ColorAlphaView 组件的创建、对应 State 对象的创建、对应 StatefulElement 的创建。自己整理一下这个问题的答案,并想一想 StatefulWidget、State 和 StatefulElement 之间的关系。


5. 总结

最后,从头到尾梳理一下,StatefulWidget 从诞生到状态类 build 的完整流程:

sh 复制代码
Element.performRebuild   # 父元素节点更新子节点
    Element.build   # 组件对象诞生
    Element.inflateWidget   # 生成子元素节点
        Widget.createElement()   # 创建子元素节点
            StatefulElement #实例化
                State #状态类对象实例化
        Element.mount()   # 创建子元素节点开始装在
          [Stateful]Element._firstBuild -> rebuild -> performRebuild -> build  # 触发元素构建流
             State.build  # 触发状态类构建

如果你有其他的看法,或者有什么想要的题目、或者想提供题目和答案,都欢迎在评论区留言。更多文章和视频知识资讯,大家可以关注我的公众号、掘金和 B 站 。

相关推荐
大龄秃头程序员11 分钟前
【小记】第一次全栈踩坑 WebSocket 404
flutter
我命由我1234513 分钟前
人脸识别 - 勒克斯(光线照射到物体表面上的明亮程度)
android·java·学习·java-ee·人脸识别·学习方法·android runtime
聚美智数1 小时前
护照OCR识别-护照图像识别-护照OCR文字识别-护照识别OCR-护照信息识别-护照OCR
android·ocr
码农coding2 小时前
android12 点击桌面应用图标启动Activity流程
android
johnsong3 小时前
深度拆解:150M循环模型如何用循环推理击败大Transformer
android·深度学习·transformer
众人皆醒我独醉3 小时前
自动扩缩容:KPA/HPA/KEDA 三条路径
面试·kubernetes·llm
黄敬峰4 小时前
一文搞懂 SQL 建表、索引与约束:博客系统数据库设计实战
面试
CedarQR4 小时前
云卓 G20 遥控器 Android 开发实录:从 USB 设备到读取摇杆/按键通道值
android·linux·无人机
大龄秃头程序员5 小时前
Dart/Flutter StatefulWidget 生命周期 + ChangeNotifier Listener 泄漏的经典坑。
flutter
pengyu5 小时前
【Kotlin 协程修仙录 · 炼虚境 · 初阶】 | 虚空造物:Channel 基础与协程间通信的管道艺术
android·前端·kotlin