【老孟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 ...
随机推荐
- 第三篇 Scrum 冲刺博客
一.站立式会议 1. 会议照片 2. 工作汇报 团队成员名称 昨日(24日)完成的工作 今天(25日)计划完成的工作 工作中遇到的困难 陈锐基 - 个人信息编辑后与组件关联- 表白墙数据用 Vuex ...
- hash相关
转译☞:https://www.cs.rice.edu/~as143/COMP441_Spring17/scribe/lect4.pdf 1 大规模图片检索问题 基于树模型的算法在分类跟聚类中很受欢迎 ...
- CC-BY-NC-SA (创作共用许可协议)
创作共用许可协议 (英语:Creative Commons license,简称CC许可) 是一种公共版权许可协议,其允许分发受版权保护的作品. 一个创作共用许可,用于一个作者想给他人分享.使用.甚至 ...
- uni-app开发中的各种问题处理
特别注意: ※:在components下的组件,图片路径用 /static/img/back.png 这样的根路径形式,不要用../static 或者 ../../static 的形式,不然很坑, ...
- latex参考文献删除[.s.l],[.s.n]
用latex写毕业论文的插入会议参考论文的时候可能会遇到编译后的文档里面一堆[.s.l],[.s.n]的问题. 这是因为ref里面会议条目找不到地址信息,所以用[.s.l],[.s.n]替代,只需要更 ...
- centos 7 yum 安装 python3
sudo yum install epel-release sudo yum install python34参考:http://stackoverflow.com/questions/8087184 ...
- js上 二.JavaScript基本语法
1.JavaScript词法结构 所谓词法结构是指一套基础性规则,用来描述如何使用这门语言来编写程序,包括如下几项: ü 字符集unicode ü 区分大小写 (true和TRUE) ü 忽略空白字符 ...
- [日常摸鱼]bzoj2038[2009国家集训队]小Z的袜子-莫队算法
今天来学了下莫队-这题应该就是这个算法的出处了 一篇别人的blog:https://www.cnblogs.com/Paul-Guderian/p/6933799.html 题意:一个序列,$m$次询 ...
- Java CPU占用过高之诊断
Redhat, java 先用top 命令(默认为cpu占用排序), 确认java占用CPU kill -3 <java pid> ps Hh -eo pid,tid,pcpu | sor ...
- SQL注入----盲注总结
参考文章:https://mp.weixin.qq.com/s?__biz=MzIzMTc1MjExOQ==&mid=2247490388&idx=1&sn=c677837d7 ...

