Flutter页面生命周期理解与分析
在Flutter的页面生命周期,着重分析StatefulWidget这个组件。因为无状态的组件StatelessWidget只有createElement 与 build两个生命周期方法,相对比较好理解,这里就不在赘述了。
StatefulWidget的生命周期方法按照时期顺序不同,可以分为三组,分别为:初始化时期、更新时期、销毁时期
1. 初始化时期的方法
createState:
当我们构建一个新的StatefulWidget时,这个会立即调用;并且这个方法必须被覆盖
initState:
这是创建Widget时调用的除构造方法外的第一个方法; 类似于Android的:onCreate() 与 IOS 的 viewDidLoad();在这个方法中通常会做一些初始化,比如channel的初始化,监听器的初始化等
2. 更新时期的方法
didChangeDependencies:
当依赖的State对象改变时会调用。
在第一次构建widget时,在initState()之后立即调用此方法;
如果StatefulWidget依赖于InheritedWidget,那么当当前的State所依赖InheritedWidget中的变量改变时会再次调用它
拓展:InheritedWidget可以高效的将数据在Widget树中向下传递、共享;
build:
每个State都需要实现的一个方法,这是一个必须实现的方法,在这里实现你要呈现的页面内容,它会在didChangeDependencies()之后立即调用。另外当调用setState后也会再次调用该方法。
didUpdateWidget:
这是一个不常用到的生命周期方法,当父组件需要重新绘制时才会调用;该方法会携带一个oldWidget参数,可以将与当前的Widget进行对比以便执行一些额外的逻辑,如
if(oldWidget.xxx != widget.xxx) {...}
3. 销毁时期的方法
deactivate:
很少使用,在组件被移除的时候调用dispose之前调用
dispose:
通常,组件被销毁时调用。通常在方法中执行一些资源的释放工作,比如监听器的卸载、channel的销毁等
下面是关于Flutter生命周期的一个具体的代码理解,我在每个方法上面也做了注释,方便理解学习:
import 'package:flutter/material.dart';
/// Flutter Widget的生命周期重点讲解StatefulWidget的生命周期
/// 因为无状态的widget StatelessWidget只有createElement 与 build两个生命周期方法
/// StatefulWidget的生命周期方法按照时期不同可以分为三组:
/// 1、初始化时期
/// createState、initState
/// 2、更新时期
/// didChangeDependencies、build、didUpdateWidget
/// 3、销毁期
/// deactivate、dispose
class WidgetLifecycle extends StatefulWidget {
// 当我们构建一个新的StatefulWidget时,这个会立即调用
// 并且这个方法必须被覆盖
@override
_WidgetLifecycleState createState() => _WidgetLifecycleState();
}
class _WidgetLifecycleState extends State<WidgetLifecycle> {
int _count = 0;
/// 这是创建Widget时调用的除构造方法外的第一个方法
/// 类似于Android的:onCreate() 与 IOS 的 viewDidLoad();
/// 在这个方法中通常会做一些初始化,比如channel的初始化,监听器的初始化等
@override
void initState() {
// TODO: implement initState
print('------------initState---------------');
super.initState();
}
/// 当依赖的State对象改变时会调用
/// a 在第一次构建widget时,在initState()之后立即调用此方法
/// b 如果StatefulWidget依赖于InheritedWidget,那么当 当前的State所依赖InheritedWidget中的变量改变时会再次调用它
/// 拓展:InheritedWidget可以高效的将数据在Widget树中向下传递、共享;
@override
void didChangeDependencies() {
print('--------------didChangeDependencies--------------');
super.didChangeDependencies();
}
/// 每个State都需要实现的一个方法
/// 这是一个必须实现的方法,在这里实现你要呈现的页面内容
/// 它会在didChangeDependencies()之后立即调用
/// 另外当调用setState后也会再次调用该方法
@override
Widget build(BuildContext context) {
print('--------------build-------------');
return Scaffold(
appBar: AppBar(
title: Text('Flutter页面生命周期'),
leading: GestureDetector(
onTap: () {
Navigator.pop(context);
},
child: Icon(Icons.arrow_back),
),
),
body: Center(
child: Column(
children: [
ElevatedButton(
onPressed: () {
setState(() {
_count++;
});
},
child: Text(
'点我',
style: TextStyle(fontSize: 26),
)),
Text('$_count')
],
),
),
);
}
/// 这是一个不常用到的生命周期方法,当父组件需要重新绘制时才会调用;
/// 该方法会携带一个oldWidget参数,可以将与当前的Widget进行对比以便执行一些额外的逻辑,如
/// if(oldWidget.xxx != widget.xxx) {...}
@override
void didUpdateWidget(covariant WidgetLifecycle oldWidget) {
print('--------------didUpdateWidget--------------');
super.didUpdateWidget(oldWidget);
}
/// 很少使用,在组件被移除的时候调用dispose之前调用
@override
void deactivate() {
print('-------------deactivate--------------');
super.deactivate();
}
/// 通常,组件被销毁时调用
/// 通常在方法中执行一些资源的释放工作,比如监听器的卸载、channel的销毁等
@override
void dispose() {
print('------------dispose-------------');
super.dispose();
}
}