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

相关推荐
wordbaby14 分钟前
Flutter Form Builder 完全指南:告别 Controller 地狱
前端·flutter
Jomurphys35 分钟前
设计模式 - 适配器模式 Adapter Pattern
android
雨白39 分钟前
电子书阅读器:解析 EPUB 底层原理与实战
android·html
g***B73841 分钟前
Kotlin协程在Android中的使用
android·开发语言·kotlin
A***27951 小时前
Kotlin反射机制
android·开发语言·kotlin
2501_916007471 小时前
iOS 应用性能测试的工程化流程,构建从指标采集到问题归因的多工具协同测试体系
android·ios·小程序·https·uni-app·iphone·webview
源码_V_saaskw1 小时前
JAVA国际版同城跑腿源码快递代取帮买帮送同城服务源码支持Android+IOS+H5
android·java·ios·微信小程序
uhakadotcom1 小时前
Loguru 全面教程:常用 API 串联与实战指南
后端·面试·github
q***d1731 小时前
Kotlin在后台服务中的框架
android·开发语言·kotlin
我要添砖java2 小时前
<JAVAEE> 多线程4-wait和notify方法
android·java·java-ee