StatelessWidget
初始化
build
通过build()渲染
StatefulWidget
初始化
State初始化时会依次执行 : 构造函数 > initState > didChangeDependencies > Widget build , 此时页面加载完成。
构造函数
调用次数:1次
这个函数严格意义上来讲不属于生命周期的一部分,因为这个时候State的widget属性为空,无法在构造函数中访问widget的属性 。但是构造函数必然是要第一个调用的。可以在这一部分接收前一个页面传递过来的数据。
intState
调用次数:1次
当插入渲染树的时候调用,这个函数在生命周期中只调用一次。这里可以做一些初始化工作,比如初始化State的变量。
在这个方法中,上下文context可用,但你还不能真正使用它,因为框架还没有完全将状态与它相关联
initState()方法完成后,State对象现在已初始化,上下文可用。
didChangeDependencies
- 初始化时,在initState()之后立刻调用
- 当依赖的InheritedWidget rebuild,会触发此接口被调用
这个函数会紧跟在initState之后调用,并且可以调用BuildContext.inheritFromWidgetOfExactType, 也就说在didChangeDependencies中,可以跨组件拿到数据
在此阶段,由于上下文context可用,您可以使用它。
运行时
build
调用次数:多次
初始化之后开始绘制界面,当setState触发的时候会再次被调用
didUpdateWidget
这个函数一般用于比较新、老Widget,看看哪些属性改变了,并对State做一些调整。
需要注意的是,涉及到controller的变更,需要在这个函数中移除老的controller的监听,并创建新controller的监听。
组件移除
组件移除,例如页面销毁的时候会依次执行:deactivate > dispose
deactivate
在dispose之前,会调用这个函数。实测在组件课件状态变化的时候会调用,当组件卸载时也会先一步dispose调用。
dispose
调用次数:1次
hot reload
reassemble
一旦到这个阶段,组件就要被销毁了,这个函数一般会移除监听,清理环境。
State
State链接到一个BuildContext,BuildContext链接到Widget的一个实例
widget
Widget State类访问其任何变量
print(widget.title);
currentState
父Widget可以通过以下方式访问其子级的状态
SnackBar是Scaffold的子Widget
final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>();
new Scaffold(
key: _scaffoldKey,
appBar: new AppBar(
title: new Text(widget.title == null ? 'ADD' : 'EDIT'),
),
body: new Container(
padding: EdgeInsets.all(20.0),
child: new Column(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
new Container(
margin: EdgeInsets.fromLTRB(0, 20, 0, 0),
child: new RaisedButton(
color: Colors.purple,
textColor: Color(0xFFFFFFFF),
onPressed: () {
_scaffoldKey.currentState.showSnackBar(
SnackBar(content: Text('Not supported.'))
);
},
child: new Text('保存'),
),
)
],
),
)
);
还有一种也可以实现类似currentState的功能
floatingActionButton: ScaffoldButton(
onPressedButton: () {
_incrementCounter();
},
));
class ScaffoldButton extends StatelessWidget {
ScaffoldButton({this.onPressedButton});
final VoidCallback onPressedButton;
@override
Widget build(BuildContext context) {
return FloatingActionButton(
onPressed: () {
print(
'FloatingActionButton onPressed context hashcode = ${context.hashCode}');
Scaffold.of(context).showSnackBar(
SnackBar(content: Text('I am context from Scaffold')));
onPressedButton();
},
tooltip: 'Increment',
child: new Icon(Icons.add),
);
}
}
祖先Widget
final MyExposingWidget widget = context.ancestorWidgetOfExactType(MyExposingWidget);
final MyExposingWidgetState state = widget?.myState;
InheritedWidget
InheritedWidget是一个特殊的Widget,您可以将其作为另一个子树的父级放在Widgets树中。该子树的所有小部件都必须能够与该InheritedWidget公开的数据进行交互。