每日一题 Flutter#11 | StatelessWidget 从诞生到 build 的流程


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

说说 StatelessWidget 从诞生到 build 的流程

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


1.调试案例

这里以最简单的颜色展示位案例来介绍,如下所示: 自定义一个 ColorView 组件展示颜色,在 MyApp 中构建。我们将专注于 ColorView 从诞生到 build 的流程:

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

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

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

class ColorView extends StatelessWidget {
  final Color color;
  const ColorView({super.key, required this.color});

  @override
  Widget build(BuildContext context) {
    return ColoredBox(color: color);
  }
}

想要知道 ColorView#build 的触发时机,只要在断点调试一下就行了。如下,可以看到 build 函数触发时的方法栈调用信息。从这里就可以分析出该方法是如何被 Flutter 框架触发的。


2. StatelessElement 与 build 的渊源

从方法栈中可以看出,ColorView#build 是被 StatelessElement#build 调用的。点击进入可以看到:

  • 这里可以通过 widget 成员拿到 ColorView 对象;
  • Widget#build 中回调的 BuildContext 参数,就是这里的 StatelessElement 对象。

3. 从 mount 开始的新生命

当继续检阅下方的方法栈,同时观察 this 对象。其中 buildperformRebuildrebuild_firstBuildmount 四个函数的 this 指向的都是 持有 ColorView 的 StatelessElement 对象。

直到 Element.inflateWidget 时 this 变成了 MyApp 对应的元素,这块代码中有着丰富的信息:

  • 在这里 newWidget 是 ColorView 组件,通过函数参数传入:
  • 在这里 newWidget 触发了 createElement 方法,创建了 newChild 元素对象。
  • newChild 元素创建完成后,执行 mount ,从而触发 build 工作流。

从这里不难看出 Element.inflateWidget 对应的对象,是父级元素节点。通过该方法得到子级元素节点进行更新。


4. 父节点更新子节点

再往下看一帧,inflateWidget 是由 updateChild 触发的,该方法返回 Element 对象。并且 newWidget 也是入参传递过来的:


再往下,来到了 ElementperformRebuild 方法:

  • 从 5715 行可以看到,上面 newWidget 的来源于 build() 函数。
  • 从 5738 行可以看到,上面 inflateWidget 返回的子元素,将作为当前元素的子节点:

当前的 Element 对象是 MyApp 组件对应的 StatelessElement, 它的 build 方法使用的是对应 Widget的 build:

也就是说,会触发 MyApp#build 返回 ColorView 对象。这就是 ColorView 组件诞生的时机:


5. 总结

到这里,从头到尾梳理一下,StatelessWidget 从诞生到 build 的完整流程。初次的构建流程发生在,父元素节点更新子节点时,会触发 build 方法得到组件,然后通过 inflateWidget 创建子元素节点,并触发子元素 mount 方法。在挂载期间触发首次的构建流程,最终触发对应组件的 build 回调。

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

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

相关推荐
yanlele1 小时前
我用爬虫抓取了 25 年 5 月掘金热门面试文章
前端·javascript·面试
花花鱼1 小时前
android studio 设置让开发更加的方便,比如可以查看变量的类型,参数的名称等等
android·ide·android studio
小兵张健2 小时前
武汉拿下 23k offer 经历
java·面试·ai编程
alexhilton3 小时前
为什么你的App总是忘记所有事情
android·kotlin·android jetpack
爱莉希雅&&&3 小时前
技术面试题,HR面试题
开发语言·学习·面试
天天扭码3 小时前
《很全面的前端面试题》——HTML篇
前端·面试·html
zhuiQiuMX5 小时前
脉脉maimai面试死亡日记
数据仓库·sql·面试
独行soc5 小时前
2025年渗透测试面试题总结-2025年HW(护网面试) 33(题目+回答)
linux·科技·安全·网络安全·面试·职场和发展·护网
库森学长6 小时前
面试官:发生OOM后,JVM还能运行吗?
jvm·后端·面试
然我6 小时前
面试必问:JS 事件机制从绑定到委托,一篇吃透所有考点
前端·javascript·面试