【老孟Flutter】为什么 build 方法放在 State 中而不是在 StatefulWidget 中

老孟导读:此篇文章是生命周期相关文章的番外篇,在查看源码的过程中发现了这一有趣的问题,欢迎大家一起探讨。
Flutter 中Stateful 组件的生命周期:http://laomengit.com/blog/20201227/Stateful%E7%BB%84%E4%BB%B6%E7%94%9F%E5%91%BD%E5%91%A8%E6%9C%9F.html
Flutter 中与平台相关的生命周期:http://laomengit.com/blog/20201227/%E7%9B%B8%E5%85%B3%E5%B9%B3%E5%8F%B0%E7%9A%84%E7%94%9F%E5%91%BD%E5%91%A8%E6%9C%9F.html
博客中还有更多精彩文章,也欢迎加入 Flutter 交流群。
灵活性
将 build 方法放在 State 中比放在 StatefulWidget 中更具灵活性,比如说,AnimatedWidget 是 StatefulWidget 的子类,AnimatedWidget 是一个抽象类,其中有一个 Widget build(BuildContext context) 的抽象方法,此方法需要子类重写,AnimatedWidget 源代码如下:
abstract class AnimatedWidget extends StatefulWidget {
...
/// Override this method to build widgets that depend on the state of the
/// listenable (e.g., the current value of the animation).
@protected
Widget build(BuildContext context);
/// Subclasses typically do not override this method.
@override
_AnimatedState createState() => _AnimatedState();
...
}
删除了一些代码,保留了重点代码。
试想一下,如果 build 方法放在 StatefulWidget 中,则 AnimatedWidget 中的 build 方法需要带一个 State 参数,如下:
abstract class AnimatedWidget extends StatefulWidget {
...
/// Override this method to build widgets that depend on the state of the
/// listenable (e.g., the current value of the animation).
@protected
Widget build(BuildContext context, AnimatedState state);
/// Subclasses typically do not override this method.
@override
_AnimatedState createState() => _AnimatedState();
...
}
但 AnimatedState 是内部实现,并不需要开放给外部(开发者),外部也不需要知道 AnimatedState 的内部实现。
闭包 this 指向异常
假设 build 方法在 StatefulWidget 中,StatefulWidget 的子类写法如下:
class MyWidget extends StatefulWidget {
final Color color;
@override
Widget build(BuildContext context, MyWidgetState state) {
print('${this.color}');
return Container();
}
}
此时的 this 指向的是 MyWidget 的实例,然后父组件改变颜色,重新构建 MyWidget 组件,前一个 MyWidget 的实例中的 this 依然指向前一个 MyWidget 的实例,颜色并未发生变化。
如果 build 方法在 State 中,代码如下:
class MyWidget extends StatefulWidget {
final Color color;
const MyWidget({Key key, this.color}) : super(key: key);
@override
_MyWidgetState createState() => _MyWidgetState();
}
class _MyWidgetState extends State<MyWidget> {
@override
Widget build(BuildContext context) {
print('${widget.color}');
return Container();
}
}
同样,父组件改变颜色,重新构建 MyWidget 组件,此时框架更新了 State 对象的 widget 属性的引用,新的 MyWidget 实例和 $ {widget.color} 将显示绿色。
性能
有状态的组件包含StatefulWidget 和 State,当有状态组件的配置发生更改时,StatefulWidget 将会被丢弃并重建,而 State 不会重建,框架会更新 State 对象中 widget 的引用,这极大的减轻了系统重建有状态组件的工作。
此方式对动画来说极为重要,由于 State 不会被重建,保留了前面的状态,不断的根据前一个状态计算下一个状态并重建其widget,达到动画的效果。
交流
老孟Flutter博客(330个控件用法+实战入门系列文章):http://laomengit.com
欢迎加入Flutter交流群(微信:laomengit)、关注公众号【老孟Flutter】:
![]() |
![]() |
【老孟Flutter】为什么 build 方法放在 State 中而不是在 StatefulWidget 中的更多相关文章
- 【老孟Flutter】源码分析系列之InheritedWidget
老孟导读:这是2021年源码系列的第一篇文章,其实源码系列的文章不是特别受欢迎,一个原因是原理性的知识非常枯燥,我自己看源码的时候特别有感触,二是想把源码分析讲的通俗易懂非常困难,自己明白 和 让别人 ...
- 【老孟Flutter】Stateful 组件的生命周期
老孟导读:关于生命周期的文章共有2篇,第一篇是介绍 Flutter 中Stateful 组件的生命周期. 博客地址:http://laomengit.com/blog/20201227/Statefu ...
- 【老孟Flutter】Flutter 中与平台相关的生命周期
老孟导读:关于生命周期的文章共有2篇,一篇(此篇)是介绍 Flutter 中Stateful 组件的生命周期. 第二篇是 Flutter 中与平台相关的生命周期, 博客地址:http://laomen ...
- 【老孟Flutter】如何提高Flutter应用程序的性能
首先 Flutter 是一个非常高性能的框架,因此大多时候不需要开发者做出特殊的处理,只需要避免常见的性能问题即可获得高性能的应用程序. 重建最小化原则 在调用 setState() 方法重建组件时, ...
- 【老孟Flutter】2021 年 Flutter 官方路线图
老孟导读:这是官方公布的2021年路线图,向我们展示了2021年 Flutter 的主要工作及计划. 原文地址:https://github.com/flutter/flutter/wiki/Road ...
- 【老孟Flutter】Flutter 2的新功能
老孟导读:昨天期待已久的 Flutter 2.0 终于发布了, Flutter Web和Null安全性趋于稳定,Flutter桌面安全性逐渐转向Beta版! 原文链接:https://medium.c ...
- 【老孟Flutter】6种极大提升Flutter开发效率的工具包
老孟导读:本文介绍6种极大提升Flutter开发效率的工具包. [1] 强大的日志软件包 在开发 Flutter 的过程中打印日志是常用的调试方式之一,但 Flutter 内置的日志打印非常简单,下面 ...
- 【老孟Flutter】自定义文本步进组件
交流 老孟Flutter博客(330个控件用法+实战入门系列文章):http://laomengit.com 欢迎加入Flutter交流群(微信:laomengit).关注公众号[老孟Flutter] ...
- 【老孟Flutter】41个酷炫的 Loading 组件库
老孟导读:目前 loading 库中包含41个动画组件,还会继续添加,同时也欢迎大家提交自己的 loading 动画组件或者直接微信发给我也可以. Github 地址:https://github.c ...
随机推荐
- 在IDEA上 使用maven进行打包时报错: Failed to execute goal org.apache.maven.plugins:maven-javadoc-plugin:2.10.2:jar
报错内容: Failed to execute goal org.apache.maven.plugins:maven-javadoc-plugin:2.10.2:jar (attach-javado ...
- Springboot mini - Solon详解(一)- 快速入门
一.Springboot min -Solon 最近号称 Springboot mini 的 Solon框架,得空搞了一把,发觉Solon确实好用,小巧而快速.那Solon到底是什么,又是怎么好用呢? ...
- 助力用户选择更优模型和架构,推动 AI机器视觉落地智能制造
智能制造的全新 "视界" 由互联网大潮掀起的技术进步,推动着智能制造成为传统制造行业面向未来.寻求突破的关键路径.通过融合机器人.大数据.云计算.物联网以及 AI 等多种技术, ...
- 前端js实现九宫格模式抽奖(多宫格抽奖)
介绍: 前端九宫格是一种常见的抽奖方式,js实现如下,掌握其原理,不论多少宫格,都可以轻松应对.(代码可复制直接运行看效果). 该案例以四宫格入门,可扩展多宫格,奖品模块的布局可自由设置. <! ...
- 最新快手抖音短视频源码web+APP架设教程+完整数据
最新更新快手抖音短视频源码web+APP架设教程+完整数据完美运行 视频直播源码,好东西,反正有人要就是了. 下载地址:https://pan.baidu.com/wap/init?surl=POU5 ...
- Linux端口被占用解决
有时候关闭软件后,后台进程死掉,导致端口被占用.下面以JBoss端口8083被占用为例,列出详细解决过程. 解决方法: 1.查找被占用的端口 netstat -tln netstat -tln | g ...
- Nginx(四):Keepalived+Nginx 高可用集群
Keepalived+Nginx 高可用集群 (主从模式) 集群架构图 安装keepalived [root@localhost ~]# yum install -y keepalived 查看状态 ...
- Web服务器-HTTP相关-快速整一个服务器响应浏览器(3.2.1)
@ 目录 1.HTTP分析 2.简单服务器 关于作者 1.HTTP分析 当你去访问一个网址的时候,浏览器会发送而各种头信息给服务器 然后服务器根据信息,返回一定数据的格式 最简单的就是下面的代码 自己 ...
- SSH,公钥,私钥的理解
参考大佬的文章:https://blog.csdn.net/li528405176/article/details/82810342 https://www.cnblogs.com/Bravew ...
- 主数据管理(MDM)的6大层级简述,你不可不知的数据治理参考!
前面我写了一篇关于对元数据和元数据管理的认知和理解的文章,有兴趣的朋友可以去看看.接下来我们讲一讲主数据管理(MDM). 主数据管理(MDM) 主数据是系统间共享数据,它是系统间信息交换的基准.主数据 ...

