Flutter 核心技术与实战
陈航
前美团点评高级技术专家
42432 人已学习
新⼈⾸单¥59
登录后,你可以任选4讲全文学习
课程目录
已完结/共 48 讲
Flutter 核心技术与实战
15
15
1.0x
00:00/00:00
登录|注册

10 | Widget中的State到底是什么?

StatefulWidget的更新会触发整个页面所有Widget的销毁和重建
声明式编程强调通过意图输出结果整体
命令式编程强调精确控制过程细节
视图和数据分离,与React设计思路一致
Widget、Element、RenderObject互相配合实现图形渲染工作
通过数据打点得出这两种方式的性能差异
改造Demo的根节点为StatefulWidget的App
不应该在build方法内部放置耗时操作
避免StatefulWidget的滥用是提升应用渲染性能的手段
Widget的UI更新机制
正确评估视图展示需求,避免无谓的StatefulWidget使用
StatefulWidget的滥用会影响Flutter应用的渲染性能
父Widget定义初始化状态,自身视图状态需要自己处理并即时更新UI展示
以State类代理Widget构建的设计方式实现
一些Widget需要处理用户交互或内部数据变化并体现在UI上
适用于静态内容的展示
StatelessWidget不带绑定状态
Widget采用由父到子、自顶向下的方式进行构建
Widget的生命周期内,应用到State中的任何更改都将强制Widget重新构建
命令式编程 vs. 声明式编程
Flutter的视图开发是声明式的
通过组合、嵌套不同类型的Widget构建任意功能、复杂度的界面
Flutter底层做了渲染优化工作
Widget是Flutter构建界面的基石
思考题
总结
StatefulWidget不是万金油,要慎用
StatefulWidget
StatelessWidget
UI编程范式
为什么不能用StatefulWidget代替StatelessWidget?
参考文章

该思维导图由 AI 生成,仅供参考

你好,我是陈航。
通过上一篇文章,我们已经深入理解了 Widget 是 Flutter 构建界面的基石,也认识了 Widget、Element、RenderObject 是如何互相配合,实现图形渲染工作的。Flutter 在底层做了大量的渲染优化工作,使得我们只需要通过组合、嵌套不同类型的 Widget,就可以构建出任意功能、任意复杂度的界面。
同时,我们通过前面的学习,也已经了解到 Widget 有 StatelessWidget 和 StatefulWidget 两种类型。StatefulWidget 应对有交互、需要动态变化视觉效果的场景,而 StatelessWidget 则用于处理静态的、无状态的视图展示。StatefulWidget 的场景已经完全覆盖了 StatelessWidget,因此我们在构建界面时,往往会大量使用 StatefulWidget 来处理静态的视图展示需求,看起来似乎也没什么问题。
那么,StatelessWidget 存在的必要性在哪里?StatefulWidget 是否是 Flutter 中的万金油?在今天这篇文章中,我将着重和你介绍这两种类型的区别,从而帮你更好地理解 Widget,掌握不同类型 Widget 的正确使用时机。
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 中文繁体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
    • 阿拉伯语
  • 解释
  • 总结

Flutter中的StatelessWidget和StatefulWidget是两种不同类型的Widget,分别适用于静态的、无状态的视图展示和需要动态变化视觉效果的场景。本文首先介绍了Flutter的UI编程范式,强调了声明式的视图开发和数据分离的重要性。通过源码分析和示例,详细解释了StatelessWidget和StatefulWidget的区别和使用场景。StatelessWidget在创建时不依赖于其他信息,不响应数据变化进行重绘;而StatefulWidget需要处理用户交互或内部数据变化,并体现在UI上。文章强调了它们各自的使用场景和必要性,避免StatefulWidget的滥用以提高Flutter应用的渲染性能。总结了Widget的更新机制和对性能的影响,并提出了在不同场景中选用何种Widget的基本原则。文章内容深入浅出,通过实际示例帮助读者更好地理解了Widget的正确使用时机和选型原则。

仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《Flutter 核心技术与实战》
新⼈⾸单¥59
立即购买
登录 后留言

全部留言(44)

  • 最新
  • 精选
  • 加温后的啤酒
    老师,有一个疑问没有理解。你文中提到如果根布局是StatefulWidget,如果调用setState,就会触发子widet的销毁和重建,影响性能。但是在真实业务场景中,我把跟控制器写成StatefulWidget,但我默认他是不可变的,所以我肯定不会主动去调用setState方法啊,那如果我不主动调用setState的话,那不就不会有应能影响了吗。这没法说明StatelessWidget的存在是必要的的??老师能解释一下吗?

    作者回复: 实际上你即使不去主动setState,对于Stateful在特定的时机也会rebuild的。具体可以参看下一篇文章

    2019-07-22
    2
    37
  • Mr.J
    构建界面时,抛开业务,光看界面,把界面按层次拆分,需要动态更新的地方,用Stateful,然后将其统一放在Stateless中,做到例如在一个小区域中,根布局也是Stateless,其中有一个控件为stateful,刷新时只刷新这个小部分,这样吗老师

    作者回复: 是的

    2019-07-21
    11
  • JW
    Element是Widget层的一个抽象用来处理真正需要重建的的Widget,它是如何来决定谁要重建谁不要重建的逻辑的?

    作者回复: 1.Widget通知Element重建的触发时机,可以参考第11篇生命周期的分享。 2.一旦Widget触发重建,Element会根据重建前后Widget树的渲染类型及属性变化情况,决定后续的复用、新建过程:比如Widget树中仅仅是调整了一个渲染样式,Flutter会通知Element直接复用现有节点,同步属性至RenderObject,触发绘制即可;如果Widget树中涉及到Widget类型的替换或变更,Flutter则会将老的Element及RenderObject摘除,让新的Widget重新走一遍创建Element和RenderObject的流程,挂载到Element树和RenderObject树上。

    2019-09-27
    8
  • (☆_☆)
    简单来说StatelessWidget就是为了提升性能而被设计出来,而完全使用StatefulWidget可能对性能有影响,所以在使用前一定要评估一下用哪个比较合适,这样理解对吗?

    作者回复: 是的

    2019-07-20
    7
  • 、轻
    这两个widget与react中的容器和组件很类似

    作者回复: 是类似的概念

    2019-08-14
    3
  • 格格
    现在Image里已经找不到_handleImageChanged方法了,好像被_handleImageFrame取代了

    作者回复: 确实,1.5还有,1.7已经把这个方法替换掉了。

    2019-08-05
    3
  • 承香墨影
    老师,你好,有个疑问希望解答。 既然 StatefulWidget 需要区分场景来使用,并且 Widget 的销毁和重建应该是 Flutter 的常态。那么在使用中,应该将 StatefulWidget 尽量的拆小,让其影响范围,尽可能的小。 这是不是就对应到 “04 | Flutter 区别于其他方案的关键技术是什么” 中讲到的 布局边界 和 重绘边界 概念。其实在实际代码中,是依赖 StatelessWidget 进行设定边界,从而隔离布局和重绘的?

    作者回复: 不是的哈。 1.重绘边界是解决同层Widget(有兄弟、有父子)之间渲染依赖出现的概念:即只要他们享用了同一个layer,则无论哪一个需要重绘,整个layer都会受到影响。 2.StatefulWidget则影响的是其子节点,一般情况下只影响重建,Element会在底层做diff,确保没有修改的不会重绘

    2019-07-30
    3
  • 矮个子先生😝
    ``` const Image({ Key key, @required this.image, // 其他参数 }) : assert(image != null), super(key: key); ``` 老师可以介绍下这个构造方法吗, 第一个Key key, : assert(image != null),super(key: key); 这三部分

    作者回复: 1.key用在Element复用过程中,控制控件如何取代树中的另一个控件。比如你在父Widget用新的image重建了Image,底层Element还是能复用的。 2.assert是断言,只在debug中生效。 3.super我们在Dart里面讲过,是调用父类的构造方法

    2019-08-13
    2
  • G
    我查了下资料,好像是说虽然widget是不可变的,但是state是可变的,也就是说state实例会被复用,并且在setstate重新生成widget树时会检查节点是否有变化,没有变化就停止遍历。另外我认为stateful的实例相比stateless更轻,毕竟没有build方法。 Ps: 在递归下降生成子树的时候,我有个疑问,flutter如何判断子树一样呢?算法是如何的?

    作者回复: 靠类型和key

    2019-07-22
    2
    2
  • Captain
    有个问题请教“虽然 Flutter 内部通过 Element 层可以最大程度地降低对真实渲染视图的修改,提高渲染效率,而不是销毁整个 RenderObject 树重建。但,大量 Widget 对象的销毁重建是无法避免的”这里 如果根节点用了Stateful,根节点setState,来改变其中变化的子节点状态(子节点状态中没有耗时操作),那Element会帮助diff出变化的子节点,避免重新构建,这样也不影响性能呀?

    作者回复: “但,大量的Widget对象的销毁重建是无法避免的”

    2019-11-14
    1
收起评论
显示
设置
留言
44
收藏
沉浸
阅读
分享
手机端
快捷键
回顶部