Flutter state生命周期方法之didChangeDependencies 、didUpdateWidget

1. didChangeDependencies

這個生命周期方法很多文章沒講明白,大都一語帶過

  • 這個方法設計的目的是什么?
    1. 告訴你你的圖層結構發(fā)生了變化
    2. 告訴你你的代碼正在執(zhí)行耗費性能的操作或者存在性能問題,圖層正在進行較大成本的重布局、重繪制、重合成
/// 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() { }
  • 依賴變化具體是指什么發(fā)生了變化?是widget的類型?布局?某些屬性值?

先拋結論:widget樹中,若節(jié)點的父級結構中的層級父級結構中的任一節(jié)點的widget類型有變化,節(jié)點調用didChangeDependencies;若僅僅是父級結構某一節(jié)點的widget的某些屬性值變化,節(jié)點不會調用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`父級結構中的層級`發(fā)生變化時(`Scaffold`、`Container`、`C`、`B` => `Scaffold`、`Container`、`C`、`SizedBox`、`B`), B會執(zhí)行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`父級結構中的任一節(jié)點的widget類型`發(fā)生變化時(`Container` => `Center`), B會執(zhí)行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樹中,若節(jié)點調用setState方法,節(jié)點本身不會觸發(fā)didUpdateWidget,此節(jié)點的子節(jié)點 調用didUpdateWidget

看個例子

A調用reload后,A不會調用didUpdateWidget,A的子節(jié)點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);
  }
}

附Demo

推薦自維護的一個Flutter下載器及相關文章:
al_downloader
Flutter 下載器 al_downloader

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

友情鏈接更多精彩內容