State生命周期
initState()
当 Widget 第一次插入到 Widget树时被调用。对于每一个 State 对象,Flutter framework只会调用一次回调。适合做一些一次性的操作,比如状态初始化,订阅子树的事件通知等。
不能在 该回调 中调用BuildContext.dependOnInheritedWidgetOfExactType,原因是在初始化完成后, Widget 树中的 InheritFromWidget 也可能会发生变化,所以正确的做法应该在 build 方法或 didChangDependencied() 中调用它。
didChangeDependencies()
当State 对象的依赖发生变化时被调用。
build()
主要用于构建 Widget 子树时被调用,它会在如下场景被调用:
1.在调用 initState 之后
2.调用 didUpdateWidget 之后
3.调用 setState 之后
4.调用 didChangeDependencies 之后
5.在 State 对象从树中一个位置移除后,又重新插入到树的其它位置之后
reassemble()
此回调是专门为开发调试而提供,在热重载 (hot reload) 时被调用,此回调在 release 下永远不会被调用。
deactivate()
当State对象从树中被移除时,会调用此方法。在一些场景下,Flutter framework 会将State 对象重新插入到树中,如包含此 State 对象的子树在树的一个位置移动到了另一个位置时。如果移除后没有重新插入到树中则紧挨着会调用 disponse 方法。
dispose()
当State对象从树中被永久移除时调用,通常用于在此回调中释放资源。
生命周期图
具体动画示例
如何获取State对象
由于 StatefulWidget 的具体逻辑都在其对应的 State 中,所以很多时候,我们需要获取 StatefulWidget 对应的 State对象来调用一些方法,比如 Scaffold 组件对应的状态类 ScaffoldState 中就定义了打开 SncakBar(路由底部提示条)的方法,我们有两种方法在子 widget 树中获取 父级 StatefulWidget的 State 对象。
通过Context获取
context 对象有一个 findAncestorStateOfType() 方法,该方法可以从当前节点沿着 widget 树向上查找指定类型的 StatefulWidget 对应的 State 对象。
findAncestorStateOfType
ScaffoldState _state = context.findAncestorStateOfType<ScaffoldState>();
of静态方法
ScaffoldState _state = Scaffold.of(context);
通过GlobalKey
GlobalKey 是 Flutter提供的一种在整个App 中引用 element 的机制。如果 一个 widget 设置了 GlobalKey,那么我们便可以通过 globalKey.currentWidget 获得该 widget 对象,globalKey.currentElement 来获得widget对应的 element 对象,如果当前 widget 是 StatefulWidget ,则可以通过 globalKey.currentState 来获得该 widget 对应的 state 对象。
示例如下:
1.给目标 StatefuleWidget 添加 GlobalKey
2.通过 GlobalKey 来获取 Satate 对象
GlobalKey<ChildState> childState = GlobalKey(); ...// childState.currentState.xxxx
需要注意的是:GlobalKey开销较大,如果有其他可选方案,应尽量避免使用它,另外同一个 GlobalKey 在整个 widget树中必须是唯一,不能重复。