老孟导读:此篇文章是生命周期相关文章的番外篇,在查看源码的过程中发现了这一有趣的问题,欢迎大家一起探讨。

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 中更具灵活性,比如说,AnimatedWidgetStatefulWidget 的子类,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 中的更多相关文章

  1. 【老孟Flutter】源码分析系列之InheritedWidget

    老孟导读:这是2021年源码系列的第一篇文章,其实源码系列的文章不是特别受欢迎,一个原因是原理性的知识非常枯燥,我自己看源码的时候特别有感触,二是想把源码分析讲的通俗易懂非常困难,自己明白 和 让别人 ...

  2. 【老孟Flutter】Stateful 组件的生命周期​

    老孟导读:关于生命周期的文章共有2篇,第一篇是介绍 Flutter 中Stateful 组件的生命周期. 博客地址:http://laomengit.com/blog/20201227/Statefu ...

  3. 【老孟Flutter】Flutter 中与平台相关的生命周期

    老孟导读:关于生命周期的文章共有2篇,一篇(此篇)是介绍 Flutter 中Stateful 组件的生命周期. 第二篇是 Flutter 中与平台相关的生命周期, 博客地址:http://laomen ...

  4. 【老孟Flutter】如何提高Flutter应用程序的性能

    首先 Flutter 是一个非常高性能的框架,因此大多时候不需要开发者做出特殊的处理,只需要避免常见的性能问题即可获得高性能的应用程序. 重建最小化原则 在调用 setState() 方法重建组件时, ...

  5. 【老孟Flutter】2021 年 Flutter 官方路线图

    老孟导读:这是官方公布的2021年路线图,向我们展示了2021年 Flutter 的主要工作及计划. 原文地址:https://github.com/flutter/flutter/wiki/Road ...

  6. 【老孟Flutter】Flutter 2的新功能

    老孟导读:昨天期待已久的 Flutter 2.0 终于发布了, Flutter Web和Null安全性趋于稳定,Flutter桌面安全性逐渐转向Beta版! 原文链接:https://medium.c ...

  7. 【老孟Flutter】6种极大提升Flutter开发效率的工具包

    老孟导读:本文介绍6种极大提升Flutter开发效率的工具包. [1] 强大的日志软件包 在开发 Flutter 的过程中打印日志是常用的调试方式之一,但 Flutter 内置的日志打印非常简单,下面 ...

  8. 【老孟Flutter】自定义文本步进组件

    交流 老孟Flutter博客(330个控件用法+实战入门系列文章):http://laomengit.com 欢迎加入Flutter交流群(微信:laomengit).关注公众号[老孟Flutter] ...

  9. 【老孟Flutter】41个酷炫的 Loading 组件库

    老孟导读:目前 loading 库中包含41个动画组件,还会继续添加,同时也欢迎大家提交自己的 loading 动画组件或者直接微信发给我也可以. Github 地址:https://github.c ...

随机推荐

  1. STL——容器(List)list 数据的存取

    list.front(); //返回第一个元素 list.back(); //返回最后一个元素 1 #include <iostream> 2 #include <list> ...

  2. win+mac全网视频无水印采集工具

    把网址填入输入框,点击下载即可.支持全网几十个平台,方便使用 window版:https://sansuinb.lanzous.com/i00Rjej0fib mac版:https://sansuin ...

  3. Android开发系列全套课程

    学习地址 https://pan.baidu.com/s/12Ljy-TDL5-P0AsYdTxGw5w#list/path=%2F

  4. 【Django Python版本对应】

    使用Python36 时应该使用Django版本1.11.4 pip install django==1.11.4 版本对应表: Django version Python versions 1.8 ...

  5. gnuplot中的一些技巧

    http://blog.csdn.net/bill_chuang/article/details/18215051 一.基础篇: 1.plot命令 基本命令:plot {<ranges>} ...

  6. Spring自带的定时任务框架Schedule的优缺点及使用

    spring自带的定时任务框架的有点:简单,拆箱即用 spring自带的定时任务框架的缺点: 不支持集群:为避免重复执行的问题 不支持生命周期统一管理:不重启服务情况下关闭,启动任务 不支持分片任务: ...

  7. webpack入门级 - 从0开始搭建单页项目配置

    前言 webpack 作为前端最知名的打包工具,能够把散落的模块打包成一个完整的应用,大多数的知名框架 cli 都是基于 webpack 来编写.这些 cli 为使用者预设好各种处理配置,使用多了就会 ...

  8. 302跳转导致的url劫持

    介绍一个   网站监测工具:iis7网站监测IIS7网站监控工具可以做到提前预防各类网站劫持,并且是免费在线查询,适用于各大站长,政府网站,学校,公司,医院等网站.它可以做到24小时定时监控,同时它可 ...

  9. 彻底理解Spring如何解决循环依赖

    Spring bean生命周期 可以简化为以下5步. 1.构建BeanDefinition 2.实例化 Instantiation 3.属性赋值 Populate 4.初始化 Initializati ...

  10. win10新版wsl2使用指南

    本篇文章会介绍win10中wsl2的安装和使用以及遇到的常见问题比如如何固定wsl2地址等问题的总结. 一.wsl2简介 wsl是适用于 Linux 的 Windows 子系统,安装指南:适用于 Li ...