Widget生命周期概述
- 监听Widget的事件
- 初始化数据
- 创建数据
- 发起网络请求
- 内存管理
- 创建和销毁数据、监听者
- 销毁timer等等
Widget生命周期
StatelessWidget生命周期
无状态,创建之后不能更新,没有dispose方法。AndroidStudio有bug导致这两个方法会调用两次。
- 构造函数,如MyHomePage()
- build(BuildContext context)
以下是自定义类MyHomePage,继承自StatelessWidget的示例:
class MyHomePage extends StatelessWidget{
final String title;
MyHomePage({this.title}){
//这是构造函数,title是可选参数
}
@override // 这个方法必须重写
Widget build(BuildContext context) {
// TODO: implement build
return null;
}
}
StatefullWidget生命周期
StatefullWidget有两个对象Widget和State构成,其整个生命周期如下:
- Widget的构造方法
- Widget的createState
- State的构造方法
- State的初始化方法initState
- State的didChangeDependencies,改变依赖关系,初始化之后会调用,当当共享的InheritedWidget变化时也会调用。(当共享的InheritedWidget变化时,所以依赖于InheritedWidget的子Widget的数据也会同步更新)
- State的build(BuildContext context),当调用setState时会再次调用build方法
- State即将从渲染树中移除时调用deactivate
- State销毁的时候调用的dispose方法
备注:StatefullWidget创建之后可以修改,通过setState更新状态。
以下是自定义类MyHomePage,继承自StatefulWidget的示例:
class MyHomePage extends StatefulWidget{
final String title;
MyHomePage({this.title}){
//这是构造函数,title是可选参数
}
@override
State<StatefulWidget> createState() {
// TODO: implement createState
return _MyHomePageState();
}
}
class _MyHomePageState extends State<MyHomePage> {
_MyHomePageState(){
//构造函数
}
@override
void initState() {// 状态初始化方法
// TODO: implement initState
super.initState();
}
@override
void didChangeDependencies() {
// TODO: implement didChangeDependencies
super.didChangeDependencies();
}
@override
Widget build(BuildContext context) {// 构建wiget的方法
// TODO: implement build
return MyData(
data: MyData.of(context).data,
child: Text(widget.title),
);
}
@override
void deactivate() {
// TODO: implement deactivate
super.deactivate();
}
@override
void dispose() {// 状态销毁防范
// TODO: implement dispose
super.dispose();
}
}
class MyData extends InheritedWidget{ //共享数据
MyData({this.data, Widget child}) : super(child:child);
final int data;
// 提供一个类方法让子Widget访问的共享数据
static MyData of(BuildContext context){
return context.dependOnInheritedWidgetOfExactType<MyData>();
}
@override
bool updateShouldNotify(MyData oldWidget) {
// TODO: implement updateShouldNotify
return oldWidget.data != data;// 不相等才更新
}
}
渲染原理
在flutter渲染流程中,有三棵重要的树,Flutter引擎是针对Render树进行渲染。Flutter引擎代码在Flutter.framework中(iOS)。三棵树分别是Widget树、Element树、RenderObject树。每个Widget都会创建一个Element,通过隐式调用createElement创建Element,然后将Element加入到Element树中。主要有三种Element:
-
RenderElement 主要创建RenderObject对象。继承自RenderObjectWidget的Widget会创建RenderElement
- 创建RenderElement
- Flutter引擎会调用mount方法,在mount方法中调用createRenderObject方法创建RenderObject
-
StatefulElement继承自ComponentElement。StatefulWidget会创建StatefulElement。
- 通过Widget调用createState创建State
- 将Widget赋值给state
- 调用state的build方法,将Element通过context回调回去
-
StatelessElement继承自ComponentElement。StatelessWidget会创建StatelessElement
- StatelessElement持有Widget
- 通过Widget调用build方法时将自己(Element)通过context参数回调回去
Widget->Element->mount->RenderObject
这三棵树中,Widget树相对不稳定,经常被更新,调用biuld后就要都重新创建。而Element则可以看做是Widget的上下文,记录Widget前后变化,将变化结果交由RenderObject渲染,实现增量更新。
- Widget与Element是对应的,但是不是一一对应的,一个Widget可能对应多个Element。
- 并不是所有的Widget都会被独立渲染,增量更新。只有继承自RenderObjectWidget才会创建RenderObject,加入到Render树里面进行渲染。RenderObject是负责渲染的。
- setState的时候实际上是标记位需要被更新,在flutter的事件循环中会被更新,调用build方法。
网友评论