实现Flutter App时,我们使用Widgets构建UI,这些widgets有两种类型,stateful和stateless,由于整个APP全部使用widget构建,所以在构建每个widget时,都需要判断使用哪种状态,这就要求必须对状态有深入了解,才能确保每个决定都是准确无误的。
Stateless
最简单直观的是读源码,如果我们打开text widget源码,会发现,这个部件没有状态可以被改变。通过构造方法把text widget 初始化,然后用properties构建要被显示的内容,父widget实际上控制着这些窗口部件的显示状态。在text widget中,父部件传入的属性,如文本。对齐方式,方向等会被其用作配置。
那么问题来了,当我们创建自己的widget的时候,什么时候用stateles部件呢?
1,可能创建一个自定义的进度控件,这个控件金使用初始化的属性来展示给用户,这样就不需要持有任何状态,因为父部件会控制其是否显示,这样父部件就管理了这个widget本身是否显示的状态了。
2,你可能创建一个用在列表中的单项widget,例如,一列蛋糕,每个蛋糕的widget都是由这个widget展示的,对于这个widget,你需要传入蛋糕的引用,从而能渲染这个widget的内容,这个widget同样不需要存储状态,它使用由父部件传入的数据,来控制对用户的显示。
以上可以看出,stateless是非动态的,它不依赖于除了传入数据以外的任何其他数据,这意味着改变其显示的唯一方式,就是改变传入其构造函数的参数。
Stateful
Stateful 是动态的,他们允许我们创建一个能动随时间改变内容的widget,并且不依赖于其初始化时被传入的静态状态,可以随着用户的输入,各种形式的异步回包或其他形式的状态变化而变化。
以image为例,_ImageState createState()=> new _ImageState();
这个被重写的方法被用来给我们的widget创建state,这个文件的_imageState持有对以下三个属性的引用
ImageStream _imageStream;
ImageInfo _imageInfo;
bool _isListeningToStream = false;
imageinfo属性用来给widget加载真是的图片,通过_handleImageChanged方法来调用state类的setState方法,
setState(() {
_imageInfo = imageInfo;
});
此时,会用新的state重新构造widget,也就是说更新后imageinfo图片被加载。
image部件以动态方式运行——监听图片引用的变化,一旦发生变化立马更新它的state。因而,它自己管理自己的state,而不是依赖于父类widget来做这件事。