Flutter中State深入分析理解
题记
—— 执剑天涯,从你的点滴积累开始,所及之处,必精益求精,即是折腾每一天。
** | 你可能需要 |
---|---|
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深入分析理解相关推荐
- flutter中 dp的理解
flutter中 dp的理解 手机屏幕是由像素点组成的. 例:iPhone 6 Plus 采用标准的 1920×1080分辨率屏幕 就是高1920个像素点,宽1080个像素点 排列成的长方形 dpi为 ...
- flutter中state生命周期与app生命周期与路由监听
State生命周期 1.第一次展示到屏幕上时会依次调用当前element的构造函数,initState,didChangeDependencies,build 2.如果只是自己发生了更新,则只会回调b ...
- flutter中state详解
State 在说到StatefulWidget之前,先说下State.State的作用有两点: 在widget构建的时候可以被同步读取: 在widget的生命周期中可能会被改变. State生命周期 ...
- element中有多个合计_深入理解 Flutter 中的 Widget, Element, RenderObject
这篇文章基于 Flutter stable v1.7 总结下 Flutter 当前的 UI 系统以及相关的概念, 在最后会通过自己组合一个 Gradient Button 按钮的方式来熟悉 Flutt ...
- Flutter中Widget 、Element、RenderObject角色深入分析
题记 -- 执剑天涯,从你的点滴积累开始,所及之处,必精益求精,即是折腾每一天. ** 你可能需要 CSDN 网易云课堂教程 掘金 EDU学院教程 知乎 Flutter系列文章 本文章将讲述 Widg ...
- flutter中的生命周期
前言 和其他的视图框架比如android的Activity一样,flutter中的视图Widget也存在生命周期,生命周期的回调函数提现在了State上面.理解flutter的生命周期,对我们写出一个 ...
- 在Flutter中嵌入Native组件的正确姿势
引言 在漫长的从Native向Flutter过渡的混合工程时期,要想平滑地过渡,在Flutter中使用Native中较为完善的控件会是一个很好的选择.本文希望向大家介绍AndroidView的使用方式 ...
- Flutter中如何选择StatelessWidget和StatefulWidget
目录 StatelessWidget和StatefulWidget的区别 StatelessWidget StatefulWidget 区别 什么情况下应该用StatelessWidget?什么情况下 ...
- java hasfocus_说说Flutter中的无名英雄 —— Focus
Focus系列的Widget及功能类在Flutter中可以说是无名英雄的存在,默默的付出但却不太为人所知.在日常开发使用中也不太会用到它,这是为什么呢?带着这个问题我们开始今天的内容. 1.Focus ...
最新文章
- 股票移动平均线matlab,股票的移动平均线 (图文)
- vue 虚拟服务器,vue+webpack项目中使用dev-server搭建虚拟服务器,请求json文件数据,实现先后台分离开发...
- 初识powershell、nuget powershell 调试
- python 取名字_python 获取如何获取类的名称?
- pod 的亲和性,反亲和性 实验
- C 语言 int 型乘法溢出问题
- Java文件类String [] list(FilenameFilter fnf)方法,带示例
- python学生名片系统_Python入门教程完整版400集(懂中文就能学会)快来带走
- matlab运行时风扇,TCFD和CAESES耦合优化案例-轴流风扇
- mysql函数commit_mysql的函数不能用commit吗?
- Squirrel Engine 曝漏洞,可导致攻击者入侵游戏和云服务
- python手写lfw数据集转pair.txt形式
- 编程语言为什么不能用中文
- Linux 磁盘动态扩容 PVM(转载)
- zabbix + nexmo = 电话告警
- GC Garbage Collectors
- prometheus targets常见报错
- JS、JNS、JP(JPE)、JNP(JPO)指令详解、从原理上解释
- Matlab绘制三维定限截面柱体;已知(隐)函数方程,绘制三维空间图形
- 菜鸟教程:HTML表单详解
热门文章
- ECCV 2020 | 小米提出 Fair DARTS :公平的可微分神经网络搜索
- CMU黑科技,手机录视频,实现人脸3D建模的高度逼真
- 深度学习之PyTorch物体检测实战——新书赠送活动
- 澎思科技新出行人再识别(ReID)算法,刷新三大数据集最高记录
- 人脸识别的前世今生:从人工特征的百花齐放到深度学习的一统江湖
- 英伟达RTX 3080值不值得抢?在TensorFlow上训练了卷积网络
- 带你自学Python系列(二):Python列表总结-思维导图
- php狼和兔子算法,PHP基于递归算法解决兔子生兔子问题php技巧
- 语音合成 | 精选论文汇总(197篇)
- 半正定问题与二阶凸锥问题(SDPSOCP)