每日一题 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 站 。

相关推荐
Sugobet3 小时前
【安卓][Mac/Windows】永久理论免费 无限ip代理池 - 适合临时快速作战
android·tcp/ip·macos·网络安全·渗透测试·ip代理池·接入点
好易学·数据结构3 小时前
可视化图解算法57:字符串的排列
数据结构·算法·leetcode·面试·笔试·回溯算法·牛客
fatiaozhang95277 小时前
创维智能融合终端SK-M424_S905L3芯片_2+8G_安卓9_线刷固件包
android·电视盒子·刷机固件·机顶盒刷机
来来走走7 小时前
Flutter开发 了解Scaffold
android·开发语言·flutter
哆啦A梦的口袋呀9 小时前
Android 底层实现基础
android
闻道且行之9 小时前
Android Studio下载及安装配置
android·ide·android studio
alexhilton9 小时前
初探Compose中的着色器RuntimeShader
android·kotlin·android jetpack
小墙程序员9 小时前
kotlin元编程(二)使用 Kotlin 来生成源代码
android·kotlin·android studio
是乐谷10 小时前
阿里招AI产品运营
人工智能·程序人生·面试·职场和发展·产品运营·求职招聘
小墙程序员10 小时前
kotlin元编程(一)一文理解 Kotlin 反射
android·kotlin·android studio