题记
—— 执剑天涯,从你的点滴积累开始,所及之处,必精益求精,即是折腾每一天。

** 你可能需要
CSDN 网易云课堂教程
掘金 EDU学院教程
知乎 Flutter系列文章

本文将从源码的角度讲述 State 的 四种状态 的变换时机,以及 从 State 的角度来理解 BuildContext 的使用时机


State 有四种状态:

  • created:当State对象被创建时候,State.initState方法会被调用;

  • initialized:当State对象被创建,但还没有准备构建时,State.didChangeDependencies在这个时候会被调用;

  • ready:State对象已经准备好了构建,State.dispose没有被调用的时候;

  • defunct:State.dispose被调用后,State对象不能够被构建。

当一个 Widget 被挂载到 Widgets 树上时,当前的StatefulWidget中通过Widget.createElement方法来创建Element,然后框架层会调用RenderObjectWidget.createRenderObject()来实例化RenderObject,然后Element(就是我们说的BuildContext)关联 Widget 与 RenderObject,这个在 Flutter中Widget 、Element、RenderObject角色深入分析 一节中有描述。

在这里 Element 与Widget 是通过 State来关联的,在 Widget 被挂载到 Widgets 树上时,会通过 StatefulWidget 的createElement 方法来创建一个StatefulElement,源码如下:

///代码清单 1-1
///StatefulWidget 源码
abstract class StatefulWidget extends Widget {/// Initializes [key] for subclasses.const StatefulWidget({ Key key }) : super(key: key);@overrideStatefulElement createElement() => StatefulElement(this);@protectedState createState();
}

然后在对应的StatefulElement 中 通过 widget 的 createState 方法来创建一个State,源码如下代码清单 1-2所示 ,在 StatefulElement 使用到的 widget 就是在代码清单 1-1 中所对应的
StatefulWidget。

///代码清单 1-2
class StatefulElement extends ComponentElement {/// Creates an element that uses the given widget as its configuration.StatefulElement(StatefulWidget widget): _state = widget.createState(),super(widget) {... ...
}

然后此时 State 的状态为 create 状态 ,需要注意的是此时 是在 StatefulElement 的构造函数中执行的,之后会在 StatefulElement 的 _firstBuild 方法中回调 initState方法,而此时State 的状态依然为 create 状态,所以 State是不可用状态,对应的 StatefulElement的(BuildContext)也是不可用状态。

对于 mounted 这个属性,在framework中是直接根据 判断当前 Widget 对应的 Element 是否为空来取值 的,如下所示:

  bool get mounted => _element != null;

StatefulElement 的创建 是在 回调 initState方法 之前,如下代码清单1-3 中所示,StatefulElement 继承于 ComponentElement,在父类 ComponentElement的构造函数中给 变量 _element 赋值, 所以在 实际开发中,在 Widget 的 initState 方法中 获取的 mounted 值为 true , State 对应的状态 为 create , Widget 与 Element 通过 State 挂载 , Element 还不可使用,也就是 context 还不可使用。

///代码清单
class StatefulElement extends ComponentElement {/// Creates an element that uses the given widget as its configuration.StatefulElement(StatefulWidget widget): _state = widget.createState(),..._state._element = this;...}

之后 State 的状态 更新 为 initialized 状态,然后回调 didChangeDependencies , initialized 状态 Element 已经将 Widget 与对应 的 RenderObject 关联好, 通过Element 可以获取 RenderObject 中进行测量与计算的一些基本信息,也就是 此时就可以使用 Element (BuildContext)。

initialized 状态 是 Element 在 Widget 与对应 的 RenderObject 形成绑定关系后,还没有里德绘制(build)前的状态,是已准备好的状态 。

之后 State 的状态 更新 为 ready 状态 ,当前(StatefulElement)回调父类(ComponentElement)的 _firstBuild 方法 ,在 ComponentElement 的 _firstBuild 方法中
rebuild ->performRebuild ,对应的RenderObject会被 插到对应的 render树上,然后绘制显示出来。

当 Widget 被 移除时 ,通过 Navigator 的 pop 或者 是在具体的 build 方法中通过变量控制将一个已在页面上渲染显示出来的Widget 移除不显示时,这个 Widget 对应的状态 变为defunct,不可用状态,同时 对应的 Element 与 Widget 、RenderObject 也会解绑,在解绑前会回调这个 Widget 的 didChangeDependencies 方法 ,此时 mounted 值为 true ,因为 对应的 Element 只是准备解绑,还不为null。

当解绑后 回调 dispose ,此时对应的 Element 已被 移除,为null ,所以 此时 被移除的 Widget中的 mounted 值为 false, 当然在这里 context 也是肯定不能使用的。


完毕

Flutter中State深入分析理解相关推荐

  1. flutter中 dp的理解

    flutter中 dp的理解 手机屏幕是由像素点组成的. 例:iPhone 6 Plus 采用标准的 1920×1080分辨率屏幕 就是高1920个像素点,宽1080个像素点 排列成的长方形 dpi为 ...

  2. flutter中state生命周期与app生命周期与路由监听

    State生命周期 1.第一次展示到屏幕上时会依次调用当前element的构造函数,initState,didChangeDependencies,build 2.如果只是自己发生了更新,则只会回调b ...

  3. flutter中state详解

    State 在说到StatefulWidget之前,先说下State.State的作用有两点: 在widget构建的时候可以被同步读取: 在widget的生命周期中可能会被改变. State生命周期 ...

  4. element中有多个合计_深入理解 Flutter 中的 Widget, Element, RenderObject

    这篇文章基于 Flutter stable v1.7 总结下 Flutter 当前的 UI 系统以及相关的概念, 在最后会通过自己组合一个 Gradient Button 按钮的方式来熟悉 Flutt ...

  5. Flutter中Widget 、Element、RenderObject角色深入分析

    题记 -- 执剑天涯,从你的点滴积累开始,所及之处,必精益求精,即是折腾每一天. ** 你可能需要 CSDN 网易云课堂教程 掘金 EDU学院教程 知乎 Flutter系列文章 本文章将讲述 Widg ...

  6. flutter中的生命周期

    前言 和其他的视图框架比如android的Activity一样,flutter中的视图Widget也存在生命周期,生命周期的回调函数提现在了State上面.理解flutter的生命周期,对我们写出一个 ...

  7. 在Flutter中嵌入Native组件的正确姿势

    引言 在漫长的从Native向Flutter过渡的混合工程时期,要想平滑地过渡,在Flutter中使用Native中较为完善的控件会是一个很好的选择.本文希望向大家介绍AndroidView的使用方式 ...

  8. Flutter中如何选择StatelessWidget和StatefulWidget

    目录 StatelessWidget和StatefulWidget的区别 StatelessWidget StatefulWidget 区别 什么情况下应该用StatelessWidget?什么情况下 ...

  9. java hasfocus_说说Flutter中的无名英雄 —— Focus

    Focus系列的Widget及功能类在Flutter中可以说是无名英雄的存在,默默的付出但却不太为人所知.在日常开发使用中也不太会用到它,这是为什么呢?带着这个问题我们开始今天的内容. 1.Focus ...

最新文章

  1. 股票移动平均线matlab,股票的移动平均线 (图文)
  2. vue 虚拟服务器,vue+webpack项目中使用dev-server搭建虚拟服务器,请求json文件数据,实现先后台分离开发...
  3. 初识powershell、nuget powershell 调试
  4. python 取名字_python 获取如何获取类的名称?
  5. pod 的亲和性,反亲和性 实验
  6. C 语言 int 型乘法溢出问题
  7. Java文件类String [] list(FilenameFilter fnf)方法,带示例
  8. python学生名片系统_Python入门教程完整版400集(懂中文就能学会)快来带走
  9. matlab运行时风扇,TCFD和CAESES耦合优化案例-轴流风扇
  10. mysql函数commit_mysql的函数不能用commit吗?
  11. Squirrel Engine 曝漏洞,可导致攻击者入侵游戏和云服务
  12. python手写lfw数据集转pair.txt形式
  13. 编程语言为什么不能用中文
  14. Linux 磁盘动态扩容 PVM(转载)
  15. zabbix + nexmo = 电话告警
  16. GC Garbage Collectors
  17. prometheus targets常见报错
  18. JS、JNS、JP(JPE)、JNP(JPO)指令详解、从原理上解释
  19. Matlab绘制三维定限截面柱体;已知(隐)函数方程,绘制三维空间图形
  20. 菜鸟教程:HTML表单详解

热门文章

  1. ECCV 2020 | 小米提出 Fair DARTS :公平的可微分神经网络搜索
  2. CMU黑科技,手机录视频,实现人脸3D建模的高度逼真
  3. 深度学习之PyTorch物体检测实战——新书赠送活动
  4. 澎思科技新出行人再识别(ReID)算法,刷新三大数据集最高记录
  5. 人脸识别的前世今生:从人工特征的百花齐放到深度学习的一统江湖
  6. 英伟达RTX 3080值不值得抢?在TensorFlow上训练了卷积网络
  7. 带你自学Python系列(二):Python列表总结-思维导图
  8. php狼和兔子算法,PHP基于递归算法解决兔子生兔子问题php技巧
  9. 语音合成 | 精选论文汇总(197篇)
  10. 半正定问题与二阶凸锥问题(SDPSOCP)