首先看看有哪些声明周期方法
class _NumState extends State<NumWidget> {
_counter = 0;
@override
void initState() {
super.initState();
//初始化状态
_counter = widget.initValue;
print("initState");
}
@override
Widget build(BuildContext context) {
print("build");
return Scaffold(
body: Center(
child: TextButton(
child: Text('$_counter'),
//点击后计数器自增
onPressed: () => setState(
() => ++_counter,
),
),
),
);
}
@override
void didUpdateWidget(NumWidget oldWidget) {
super.didUpdateWidget(oldWidget);
print("didUpdateWidget ");
}
@override
void deactivate() {
super.deactivate();
print("deactivate");
}
@override
void dispose() {
super.dispose();
print("dispose");
}
@override
void reassemble() {
super.reassemble();
print("reassemble");
}
@override
void didChangeDependencies() {
super.didChangeDependencies();
print("didChangeDependencies");
}
}
在新路由中,我们只显示一个NumWidget
class TestWidget extends StatelessWidget {
const TestWidget({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return CartWidget();
}
}
运行应用打开这个路由,会执行以下生命周期。
I/EGL_emulation(18206): initState
I/EGL_emulation(18206): didChangeDependencies
I/EGL_emulation(18206): build
然后我们点击⚡️按钮热重载,会执行以下声明周期:
I/EGL_emulation(18206): reassemble
I/EGL_emulation(18206): didUpdateWidget
I/EGL_emulation(18206): build
接下来,我们在 widget 树中移除CartWidget,将 TestWidget 的 build方法改为:
class TestWidget extends StatelessWidget {
const Test({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
// return CartWidget();
return Text('我是新的控件');
}
}
点击⚡️按钮热重载
I/EGL_emulation(18206): reassemble
I/EGL_emulation(18206): deactive
I/EGL_emulation(18206): dispose
注意:在继承StatefulWidget重写其方法时,对于包含@mustCallSuper标注的父类方法,都要在子类方法中先调用父类方法.
-
initState:
当 widget 第一次插入到 widget 树时会被调用,对于每一个State对象,Flutter 框架只会调用一次该回调,所以,通常在该回调中做一些一次性的操作,如状态初始化、订阅子树的事件通知等。不能在该回调中调用BuildContext.dependOnInheritedWidgetOfExactType
(该方法用于在 widget 树上获取离当前 widget 最近的一个父级InheritedWidget
),原因是在初始化完成后, widget 树中的InheritFrom widget
也可能会发生变化,所以正确的做法应该在在build()
方法或didChangeDependencies()
中调用它。 -
didChangeDependencies():
当State对象的依赖发生变化时会被调用;例如:在之前build()
中包含了一个InheritedWidget
,然后在之后的build() 中Inherited widget
发生了变化,那么此时InheritedWidget
的子 widget 的didChangeDependencies()
回调都会被调用。典型的场景是当系统语言Locale
或应用主题改变时,Flutter 框架会通知 widget 调用此回调。需要注意,组件第一次被创建后挂载的时候(包括重创建)对应的didChangeDependencies
也会被调用。 -
build():
此回调读者现在应该已经相当熟悉了,它主要是用于构建 widget 子树的,会在如下场景被调用:在调用initState()之后。 在调用didUpdateWidget()之后。 在调用setState()之后。 在调用didChangeDependencies()之后。 在State对象从树中一个位置移除后(会调用deactivate)又重新插入到树的其它位置之后。
-
reassemble():
此回调是专门为了开发调试而提供的,在热重载(hot reload)时会被调用,此回调在Release模式下永远不会被调用。 -
didUpdateWidget ():
在 widget 重新构建时,Flutter 框架会调用widget.canUpdate
来检测 widget 树中同一位置的新旧节点,然后决定是否需要更新,如果widget.canUpdate
返回true则会调用此回调。正如之前所述,widget.canUpdate
会在新旧 widget 的 key 和 runtimeType 同时相等时会返回true,也就是说在在新旧 widget 的key和runtimeType同时相等时didUpdateWidget()
就会被调用。 -
deactivate():
当 State 对象从树中被移除时,会调用此回调。在一些场景下,Flutter 框架会将 State 对象重新插到树中,如包含此 State 对象的子树在树的一个位置移动到另一个位置时(可以通过GlobalKey
来实现)。如果移除后没有重新插入到树中则紧接着会调用dispose()
方法。 -
dispose():
当 State 对象从树中被永久移除时调用;通常在此回调中释放资源。
以上内容均借鉴了这个大佬写的教程他介绍的更详细,咱们作为学习做个简单的记录,如有不合适联系删除【抱拳】【抱拳】