这两个类在framework.dart中,可见其重要性。其实自己看过了多次,不过现在还是想用文字记录着再看一次,因为它们太重要了。
两者还有一个父类,Widget
1 |
|
StatelessWidget
1 |
|
StatefulWidget
状态信息可以异步读取
状态信息可以在Widget的生命周期内修改
注意到,StatefulWidget本身是不可变,只有State是可变的,其属性State是final field,创建后后指向。
每次 inflate Widget 便会调用createSate()。从树中移除后,重新插入也会导致创建createState
当使用GlobalKey时,移动Element的位置,可以复用原来的State,这样我们可以移动一个子树,注意移除还插入的动作需要在动画的同一帧完成。
性能考虑:
将State尽可能放到叶子,下放
要是子树不会改变,缓存子树
避免修改子树的深度和类型,转而使用属性来控制相应的状态。这个可以用 canUpdate() 来理解,改变状态来可以避免原先Element被替换。
若是子树深度非要改变,子树使用GlobalKey。使用KeyedSubtree要是不方便指定Widget来使用GlobalKey。
State
Widget创建的State绑定到 BuildContext 被认为是 mounted状态,其关联关系绑定后不可变了。
绑定后,可以根据Context来 initSate()
1 | abstract class StatefulWidget{ |
一个设计问题?为什么 Build()放在State,而不是放在StatefulWidget
没有在StatefulWidget中这么写,给StatefulWidget更多的灵活性,如何理解呢?
1 | Widget build(BuildContext context, State state) {} |
AnimateWidget是很多动画的表示,假设在StatefulWidget中防止Build方法,则导致Widget依赖很多动画的实现State
概念上,StatelessWidget是StatefulWidget的子类,若是将StatefulWidget多了个方法,那么将不可能了
State中的注册和注销
假设我们构造的目标对象,依赖了某些对象,我们该在什么时机注册和注销这些依赖呢
initState() 中订阅
didUpdateWidget() 中,若是需要,unSubscribe原先的源并更换新的源
dispose() 注销所有的源