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

相关推荐
雨季6662 小时前
Flutter 三端应用实战:OpenHarmony “专注时光盒”——在碎片洪流中守护心流的数字容器
开发语言·前端·安全·flutter·交互
kirk_wang2 小时前
Flutter艺术探索-Flutter相机与相册:camera库与image_picker集成
flutter·移动开发·flutter教程·移动开发教程
子春一3 小时前
Flutter for OpenHarmony:构建一个 Flutter 贪吃蛇游戏,深入解析状态机、碰撞检测与响应式游戏循环
flutter·游戏
2601_949543013 小时前
Flutter for OpenHarmony垃圾分类指南App实战:主题配置实现
android·flutter
2601_949833394 小时前
flutter_for_openharmony口腔护理app实战+知识实现
android·javascript·flutter
晚霞的不甘4 小时前
Flutter for OpenHarmony从基础到专业:深度解析新版番茄钟的倒计时优化
android·flutter·ui·正则表达式·前端框架·鸿蒙
Warren984 小时前
Pytest Fixture 作用域详解:Function、Class、Module、Session 怎么选
面试·职场和发展·单元测试·pytest·pip·模块测试·jira
ujainu4 小时前
无物理引擎实现吸附轨道逻辑 —— Flutter + OpenHarmony 实战指南
flutter·游戏·openharmony
kirk_wang4 小时前
Flutter艺术探索-Flutter地图与定位:google_maps_flutter与geolocator
flutter·移动开发·flutter教程·移动开发教程
努力学算法的蒟蒻4 小时前
day73(2.1)——leetcode面试经典150
面试·职场和发展