1. didChangeDependencies
这个生命周期方法很多文章没讲明白,大都一语带过
- 这个方法设计的目的是什么?
- 告诉你你的图层结构发生了变化
- 告诉你你的代码正在执行耗费性能的操作或者存在性能问题,图层正在进行较大成本的重布局、重绘制、重合成
/// Subclasses rarely override this method because the framework always
/// calls [build] after a dependency changes. Some subclasses do override
/// this method because they need to do some expensive work (e.g., network
/// fetches) when their dependencies change, and that work would be too
/// expensive to do for every build.
@protected
@mustCallSuper
void didChangeDependencies() { }
- 依赖变化具体是指什么发生了变化?是widget的类型?布局?某些属性值?
先抛结论:widget树中,若节点的父级结构中的层级
或 父级结构中的任一节点的widget类型
有变化,节点会
调用didChangeDependencies;若仅仅是父级结构某一节点的widget的某些属性值
变化,节点不会
调用didChangeDependencies
看个例子
- A
import 'package:flutter/material.dart';
class A extends StatefulWidget {
@override
State<StatefulWidget> createState() => AState();
}
class AState extends State<A> {
bool bDependenciesShouldChange = false;
@override
void initState() {
super.initState();
Future.delayed(Duration(seconds: 15), () {
bDependenciesShouldChange = true;
setState(() {});
});
}
@override
Widget build(BuildContext context) {
/// B`父级结构中的层级`发生变化时(`Scaffold`、`Container`、`C`、`B` => `Scaffold`、`Container`、`C`、`SizedBox`、`B`), B会执行didChangeDependencies
return bDependenciesShouldChange
? Scaffold(
body: Container(
height: 500,
alignment: Alignment.centerLeft,
child: C(child: B()),
))
: Scaffold(
body: Container(
height: 500,
alignment: Alignment.centerLeft,
child: C(child: SizedBox(width: 20, height: 50, child: B())),
));
// /// B`父级结构中的任一节点的widget类型`发生变化时(`Container` => `Center`), B会执行didChangeDependencies
// return bDependenciesShouldChange
// ? Scaffold(body: Center(child: C(child: B())))
// : Scaffold(
// body: Container(
// height: 500,
// alignment: Alignment.centerLeft,
// child: C(child: B()),
// ));
}
@override
void didChangeDependencies() {
super.didChangeDependencies();
debugPrint("AdidChangeDependencies");
}
}
class B extends StatefulWidget {
@override
State<StatefulWidget> createState() => BState();
}
class BState extends State<B> {
@override
Widget build(BuildContext context) {
return Center(child: Text("B"));
}
@override
void didChangeDependencies() {
super.didChangeDependencies();
debugPrint("BdidChangeDependencies");
}
}
class C extends StatefulWidget {
final Widget child;
C({Key key, this.child}) : super(key: key);
@override
State<StatefulWidget> createState() => CState();
}
class CState extends State<C> {
@override
Widget build(BuildContext context) {
return widget.child;
}
@override
void didChangeDependencies() {
super.didChangeDependencies();
debugPrint("CdidChangeDependencies");
}
}
2. didUpdateWidget
先抛结论:widget树中,若节点调用setState方法,节点本身不会
触发didUpdateWidget,此节点的子节点 会
调用didUpdateWidget
看个例子
A调用reload后,A不会
调用didUpdateWidget,A的子节点B会
调用didUpdateWidget
- A
class A extends StatefulWidget {
@override
State<StatefulWidget> createState() => AState();
}
class AState extends State {
@override
Widget build(BuildContext context) {
return B();
}
/// AState调用此方法后,[AState.didUpdateWidget]不会调用, [BState.didUpdateWidget]会调用
void reload() {
setState(() {});
}
@override
void didUpdateWidget(StatefulWidget oldWidget) {
super.didUpdateWidget(oldWidget);
}
}
class B extends StatefulWidget {
@override
State<StatefulWidget> createState() => AState();
}
class BState extends State {
@override
Widget build(BuildContext context) {
return null;
}
/// AState调用[AState.reload]后,[AState.didUpdateWidget]不会调用, [BState.didUpdateWidget]会调用
@override
void didUpdateWidget(StatefulWidget oldWidget) {
super.didUpdateWidget(oldWidget);
}
}
推荐自维护的一个Flutter下载器及相关文章:
al_downloader
Flutter 下载器 al_downloader