Flutter中Stateless和Stateful的区别

实现Flutter app时,我们用widgets来构建app的UI。这些widgets有两种类型——statefule(有状态) 和 stateless(无状态)。本文中,笔者将深入探讨这两种类型的区别,从而帮大家更好地理解widget,掌握不同类型widget的使用时机。

Stateless widgets

当你创建的widge不需要管理任何形式的内部state时,你就应当使用StatelessWidgets。这类widget不需要任何可变的state,然后会在初始化数据后被使用。

例如,我们可以看一些我们熟知的Stateless widget:


这三个widget只是flutter部件集中的一小部分stateless widget。那么Stateless到底指的是什么呢?最简单直观的方法就是去读这些widget的源码(本文中没有源码分析,但是你可以点击这里看Text Widget的源码)。如果我们打开Text widget的源码,你会发现,这个部件没有状态可以被改变。通过构造方法把Text Widget初始化,然后用properties构建要被显示的内容,父widget实际上控制着这些这些窗口部件的显示状态。

在Text widget的例子中,父部件传入的属性,如文本,对齐方式,方向等会被其用作配置。前文我提到Stateless部件也是同样的用法。

但是当我们创建自己的widgets时,我们什么时候用stateless部件呢?考虑如下场景:

  • 你可能创建一个自定义的进度条控件,这个控件仅使用初始化的属性来展示进度给用户。这样就不需要持有任何状态,因为父部件会控制其是否显示,这样父部件就管理了这个widget本身是否显示的状态了。
  • 你可能创建一个用在列表中的单项widget,例如,一列蛋糕,每个蛋糕的widget都是由这个widget展示的。对于这个widget,你需要传入蛋糕的引用,从而能渲染这个widget的内容。这个widget同样不需要存储状态,它使用由父部件传入的数据,来控制对用户的显示。

从以上我们可以看出,Stateless widget是非动态的,它不依赖于除了传入的数据以外任何其他数据,这意味着改变其显示的唯一方式,就是通过改变传入其构造函数的参数。

Stateful widgets

另一方面,stateful widgets是动态的。他们允许我们创建一个能动随时间动态改变器内容的widget,并且不依赖于其初始化时被传入的静态状态。他们可以随着用户的输入,各种形式的异步回包或其他形式的状态变化而改变。

例如,我们可以看一些我们了解的stateful widget:

以上是flutter部件集中的一部分stateful widget。那么具体可变状态体现在哪里呢?(同样,你首先可以自己去看源码)以Image widget为例,我们可以发现这个文件有一点不同。首先,Image类继承自StatefulWidget类,然后和之前的Stateless widget一样,Image类的构造函数会接受要被这个类使用的属性参数。然而不同的是这里:

_ImageState createState() => new _ImageState();

这个被重写的方法被用来给我们的widget创建state。不用对Image类的工作方式了解的多明确,你可以发现这个文件的_ImageState持有对以下三个属性的引用:

ImageStream _imageStream;
ImageInfo _imageInfo;
bool _isListeningToStream = false;

ImageInfo属性用来给widget加载真实的图片。通过_handleImageChanged方法来调用State类的setState方法,表示:“hey,有些数据变啦,我们需要更新我们的State!”。

setState(() { _imageInfo = imageInfo;
});

此时,会用新的state重新构造widget,也就是说更新后imageInfo中的图片被加载。在这里,Image部件以动态方式运行 —— 监听图片引用的变化,一旦发生改变立马更新它的state。因而,它自己管理自己的state,而不是依赖于父类widget来做这个事情。值得去研究一下其他的Stateful widget是怎么运作的,它会帮你更好的理解什么时候该用stateful部件,什么时候该用stateless。一些简单的widget应该持有state的例子:

  • 比如我们构造一个控件来标识一个事物是否被用户标记。在这里,我们的可点击的view就应该持有一个对是否标记的引用 —— 这个状态应该随着每次点击做改变,同时这个类的构造方法也应该随着是否标记来设置不同的图标。
  • 比如我们有一个持有对当前选中项数目的widget,点击“+”会增加这个值。这里,我们的item就应该持有一个数目state,每次点击“+”,这个数目state都应该更新,并且这个数目在widget上的表现也应该在build方法里面更新。

希望这篇文章能帮你更好的理解stateless和stateful的区别。对这两者的正确使用,可以简化app结构,并让其可以更好地被复用或者调试。

原文:Stateful or Stateless widgets?

Flutter中Stateless和Stateful的区别相关推荐

  1. Flutter 中 stateless 和 stateful widget 的区别[Flutter专题60]

    Flutter 中 stateless 和 stateful widget 的区别 介绍 要在 Flutter 中构建任何应用程序,我们必须创建一个小部件类,它是 Flutter 应用程序的构建块.F ...

  2. 歪解stateful session bean 和 stateless session bean的区别。

    歪解stateful session bean 和 stateless session bean的区别. 无状态bean嘛,比如在家里你要上厕所,无状态bean每次提供得是全新的马桶,有状态提供得是上 ...

  3. Flutter中Flexible和Expanded区别

    Flutter中Flexible和Expanded区别 在官网的介绍中感觉说的很模糊: Flexible:Flexible是一个控制Row.Column.Flex等子组件如何布局的组件,Flexibl ...

  4. flutter 局部状态和全局状态区别_给 Android 开发者的 Flutter 指南

    这篇文档旨在帮助 Android 开发者利用既有的 Android 知识来通过 Flutter 开发移动应用.如果你了解 Android 框架的基本知识,你就可以使用这篇文档作为 Flutter 开发 ...

  5. element中有多个合计_深入理解 Flutter 中的 Widget, Element, RenderObject

    这篇文章基于 Flutter stable v1.7 总结下 Flutter 当前的 UI 系统以及相关的概念, 在最后会通过自己组合一个 Gradient Button 按钮的方式来熟悉 Flutt ...

  6. 官方文档——一篇文章弄懂Flutter中的布局

    来自Flutter中文资源主页https://flutter.cn/ 原文:https://flutter.cn/docs/development/ui/layout Flutter 中的布局 要点 ...

  7. Flutter中如何利用StreamBuilder和BLoC来控制Widget状态

    参考文章:Reactive Programming - Streams - BLoC (为了便于阅读,略去了原文中的一些跟StreamBuilder和Bloc无关的拓展概念,比如RxDart.Demo ...

  8. flutter 局部状态和全局状态区别_Android 开发者遇到 5G、AI,写给 Android 开发者的 Flutter 指南

    ​前言 Flutter 是 Google 用以帮助开发者在 iOS 和 Android 两个平台开发高质量原生 UI 的移动 SDK.Flutter 兼容现有的代码,免费并且开源,在全球开发者中广泛被 ...

  9. flutter bloc_如何使用BLoC模式处理Flutter中的状态

    flutter bloc Last year, I picked up Flutter and I must say it has been an awesome journey so far. Fl ...

最新文章

  1. 中文版开源!这或许是最经典的Python编程教材
  2. MySQL INNER JOIN:内连接查询
  3. Python多任务(多线程执行带有参数的任务,利用threading创建线程时传入参数--args参数和kwargs参数)
  4. LOL手游2.3版皮肤大更新,端游玩家:新春级和珍稀级会返场吗
  5. vs环境下C++dll生成和使用(基础篇)
  6. 爆笑!物理书上的照片能不能好好选选啊喂!
  7. frame越过另一个frame_拥抱swoole(三)之用php实现一个混合服务器
  8. html+注释格式化,使用xml注释来生成格式化的html输出
  9. Python基础之补充1
  10. [转载]JAVA操作符
  11. 试比较瀑布模型、快速原型模型、增量模型和螺旋模型的优缺点
  12. 八皇后问题(详解带注释)
  13. Java开发入职新公司如何快速上手业务?
  14. python 优雅退出_Python学习教程:Python 使用 backoff 更优雅的实现轮询
  15. 量子计算发展史上的27个里程碑事件
  16. 致 Embarcadero 客户及经销伙伴信函
  17. Windows下的gotoxy 函数
  18. Unity 小游戏-打砖块
  19. VC版本号与VS对应关系
  20. Android4学习-高级编程读书笔记开始篇

热门文章

  1. node + multer 实现文件上传
  2. Layui下拉框的绑定
  3. TCGA数据库ceRNA网络构建(三)ceRNA网络构建
  4. 计算机制作母亲节,“妈妈,我想对你说”---计算机学院举办母亲节感恩活动
  5. 当不想前行的时候,就静静的看看书吧
  6. java web邮箱找回密码
  7. php 短信验证码30分钟,php下发短信验证码60秒简单验证
  8. BTrace快速入门
  9. Android6.0权限大全和权限分类
  10. 券商要知道的港美股软件交易系统板块展示图