生命周期的概念
- 什么是生命周期?
生命周期说白了就是回调的方法函数,让开发者知道当前的Widget处于什么样的状态
- 有什么作用?
- 监听Widget的事件
- 初始化数据:创建数据、发送网络请求
- 内存管理:销毁数据和监听者、销毁Timer等
Widget的生命周期
- 无状态的Stateless
- 构造方法
build方法
class SearchCell extends StatelessWidget {// const SearchCell();SearchCell(){print('构造方法被调用');};@overrideWidget build(BuildContext context) {print('build方法被调用');return Container();}

- 有状态的Stateful(包含两个对象Widget、State)
- Widget的构造方法
- Widget的CreatState
- State的构造方法
- State的initState方法
- didChangeDependencies方法:改变依赖关系,依赖(共享数据)的InheritedWidget发生变化之后,方法也会调用
- State的build方法,当调用setState方法,会重新调用build进行渲染
- State的dispose方法,销毁时调用
class SearchPage extends StatefulWidget {SearchPage(){print('Widget的构造方法');}@override_SearchPageState createState() {print('Widget的CreatState');return _SearchPageState();}}class _SearchPageState extends State<SearchPage> {_SearchPageState() {print('State的构造方法');}@overridevoid initState() {// TODO: implement initStatesuper.initState();print('State的initState方法');}@overridevoid dispose() {// TODO: implement disposesuper.dispose();print('State的dispose方法');}@overridevoid didChangeDependencies() {// TODO: implement didChangeDependenciessuper.didChangeDependencies();print('didChangeDependencies方法');}@overrideWidget build(BuildContext context) {print('State的build方法');return Container();}}
使用Flutter Hot Restart
使用Flutter Hot Reload
setState方法内部:

_element的类型:StatefulElement? _element;
BuildContext get context {assert(() {if (_element == null) {throw FlutterError('This widget has been unmounted, so the State no longer has a context (and should be considered defunct). \n''Consider canceling any active work during "dispose" or using the "mounted" getter to determine if the State is still active.',);}return true;}());return _element!;}StatefulElement? _element;
从这里能够看出这里的_element其实就是当前的context,所以这也就是为什么调用setState方法会重新走一遍build的原因 => 等价代换如下:
context as StatefulElement;context.markNeedsBuild();
上面两行代码的效果和setState是一样的!
- InheritedWidget数据共享
如果A的数据需要传递到B的话,我们之前是在构造方法里面传递,如下面的示例代码,这种的didChangeDependencies方法只会调用一次。
class InheritedDemo extends StatefulWidget {const InheritedDemo({Key? key}) : super(key: key);@override_InheritedDemoState createState() => _InheritedDemoState();}class _InheritedDemoState extends State<InheritedDemo> {int _count = 0;@overrideWidget build(BuildContext context) {return Column(children: [SizedBox(height: 200),TextCount(count: _count),// _count通过组件的构造方法来传递ElevatedButton(onPressed: () {_count++;setState(() {});},child: Text('点我'),)],);}}class TextCount extends StatefulWidget {final int count;TextCount({required this.count});@override_TextCountState createState() => _TextCountState();}class _TextCountState extends State<TextCount> {@overrideWidget build(BuildContext context) {return Text(widget.count.toString());}}
这里我们介绍一个新的数据共享的方式InheritedWidget,看一下该组件的内部方法还是比较简单的:
abstract class InheritedWidget extends ProxyWidget {// 父类的构造方法const InheritedWidget({ Key? key, required Widget child }): super(key: key, child: child);@overrideInheritedElement createElement() => InheritedElement(this);@protectedbool updateShouldNotify(covariant InheritedWidget oldWidget);}
- 首先定义一个共享数据类继承于该小部件
- 其次实现构造方法,该构造方法可以参考
InheritedWidget抽象基类的方法 - 最后定义一个类方法提供给外部使用来便捷获取数据
- 同时选择实现更新数据就去通知依赖共享数据的小部件
```dart
class MyData extends InheritedWidget {
final int count;
// 构造方法
const MyData({required this.count, required Widget child})
// 类方法提供给外部使用方便 拿到数据 static MyData? of(BuildContext context) { return context.dependOnInheritedWidgetOfExactType: super(child: child);
(); }
// 数据发生变化时 是否通知 @override bool updateShouldNotify(MyData oldWidget) { return oldWidget.count != count; } }
那怎么使用,才能把数据和组件关联上呢?- 保存和关联:在build方法里面使用构造方法,拿到数据保存和关联也就是需要使用该数据的小部件- 取出:在小部件需要使用的时候调用类方法拿出```dartclass _InheritedDemoState extends State<InheritedDemo> {int _count = 0;@overrideWidget build(BuildContext context) {return MyData( // 在这里使用count: _count,child: ....);}}class _TextCountState extends State<TextCount> {@overrideWidget build(BuildContext context) {return Text(MyData.of(context)!.count.toString());}@overridevoid didChangeDependencies() {// TODO: implement didChangeDependenciessuper.didChangeDependencies();print('didChangeDependencies方法');}}
此时每次点击的时候都会再次调用didChangeDependencies方法
Widget的渲染原理
并不是所有的Widget都会被独立渲染!只有集成RenderObjectWidget的才会创建RenderObject对象!在Flutter渲染的流程中,有三个重要的树
- Widget树、Element树、Render树
- 每一个Widget都会创建一个Element对象
- 隐式调用
creatElement方法,Element加入Element树- RenderElement
- StatefulElement
- StatelessElement
- RenderElement
RenderElement主要是创建RenderObject对象(继承RenderObjectWidget的Widget会创建RenderElement)- Fluter会调用mount方法,创建
RanderObject对象
- Fluter会调用mount方法,创建
- StatefulElement
StatefulElement继承ComponentElement(StatefulWidget会创建StatefulElement)- 调用creatState方法,创建State
- 将Widget赋值给state
state._widget = widget; - 调用state的build方法并且将Element也就是自己本身传递出去

- StatelessElement
StatelessElement继承ComponentElement(StatelessWidget会创建StatelessElement)- Stateless会创建Element
- 然后Element创建就会调用mount方法
- mount里面会调用widget的bulid方法进行渲染,并且将Element自己本身传递出去

