做为一个Android开发者,必定会对Activity的生命周期有这很深入的印象,而当你在使用Flutter时,其中Widget就是View,其生命周期就是从View建立到销毁的过程。 Widget分为StatelessWidgetStatefulWidget 两种,这两种Widget的生命周期分别以下。bash
无状态Widget的生命周期很简单,它只有一个生命周期:build网络
build函数用来构建视图,每次页面刷新是被调用,典型的用法以下:app
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return new MaterialApp(
title: 'Welcome to Flutter',
home: new Scaffold(
appBar: new AppBar(
title: new Text('Welcome to Flutter'),
),
body: new Center(
child: new Text('Hello World'),
),
),
);
}
}
复制代码
StatefulWidget生命周期整理以下图:less
createState必须且仅执行一次,它用来建立state,当建立StatefulWidget时,该放方法被执行ide
在建立StatefulWidget后,initState是第一个被调用的方法,同createState同样只被调用一次,此时widget的被添加至渲染树,mount的值会变为true,但并无渲染。能够在该方法内作一些初始化操做。在在override时要低啊用super.initState()函数
@override
void initState() {
super.initState();
...
}
复制代码
当widget第一次被建立时,didChangeDependencies紧跟着initState函数以后调用,在widget刷新时,该方法不会被调用。它会在“依赖”发生变化时被Flutter Framework调用,这个依赖是指widget是否使用父widget中InheritedWidget的数据。也便是只有在widget依赖的InheritedWidget发生变化以后,didChangeDependencies才会调用。 这种机制可使子组件在所依赖的InheritedWidget变化时来更新自身!好比当主题、locale(语言)等发生变化时,依赖其的子widget的didChangeDependencies方法将会被调用。ui
//经过继承InheritedWidget,将当前计数器点击次数保存在ShareDataWidget的data属性中:
class ShareDataWidget extends InheritedWidget {
ShareDataWidget({
@required this.data,
Widget child
}) :super(child: child);
final int data; //须要在子树中共享的数据,保存点击次数
//定义一个便捷方法,方便子树中的widget获取共享数据
static ShareDataWidget of(BuildContext context) {
return context.inheritFromWidgetOfExactType(ShareDataWidget);
}
//该回调决定当data发生变化时,是否通知子树中依赖data的Widget
@override
bool updateShouldNotify(ShareDataWidget old) {
//若是返回true,则子树中依赖(build函数中有调用)本widget
//的子widget的`state.didChangeDependencies`会被调用
return old.data != data;
}
}
class _TestWidget extends StatefulWidget {
@override
__TestWidgetState createState() => new __TestWidgetState();
}
//而后咱们实现一个子组件_TestWidget,在其build方法中引用ShareDataWidget中的数据。
class __TestWidgetState extends State<_TestWidget> {
@override
Widget build(BuildContext context) {
//使用InheritedWidget中的共享数据
return Text(ShareDataWidget
.of(context)
.data
.toString());
}
@override
void didChangeDependencies() {
super.didChangeDependencies();
//父或祖先widget中的InheritedWidget改变(updateShouldNotify返回true)时会被调用。
//若是build中没有依赖InheritedWidget,则此回调不会被调用。
print("Dependencies change");
}
}
复制代码
注意:若是_TestWidget的build方法中没有使用ShareDataWidget的数据,那么它的didChangeDependencies()将不会被调用,由于它并无依赖ShareDataWidget。在依赖改变以后build方法也会被调用,因此在大多数场景下都无需使用didChangeDependencies。然而若是你须要在依赖改变后执行一些昂贵的操做,好比网络请求,这时最好的方式就是在此方法中执行,这样能够避免每次build()都执行这些昂贵操做。this
build函数会在widget第一次建立时紧跟着didChangeDependencies方法以后和UI从新渲染是时调用。build只作widget的建立操做,若是在build里作其余操做,会影响UI的渲染效果spa
当组件的状态改变的时候就会调用didUpdateWidget,好比调用了setState.code
当要将State对象从渲染树中移除的时候,就会调用 deactivate 生命周期,这标志着 StatefulWidget将要销毁。页面切换时,也会调用它,由于此时State在视图树中的位置发生了变化可是State不会被销毁,而是从新插入到渲染树中。 重写的时候必需要调用 super.deactivate()
从渲染树中移除view的时候调用,State会永久的从渲染树中移除,和initState正好相反mount值变味false。这时候就能够在dispose里作一些取消监听操做。
函数 | 调用次数 | 调用时间 |
---|---|---|
createState | 1 | 第一次建立 |
initState | 1 | 第一次建立 |
didChangeDependencies | n | 第一次建立和依赖变化时 |
build | n | 第一次建立和UI从新渲染时 |
didUpdateWidget | n | 第一次建立和UI从新渲染时 |
deactivate | n | state对象将要移除时 |
dispose | 1 | state对象移除 |