1. 簡(jiǎn)介
InheritedWidget是 Flutter 中非常重要的一個(gè)功能型組件茬贵,它提供了一種在 widget 樹中從上到下共享數(shù)據(jù)的方式湾揽,比如我們?cè)趹?yīng)用的根 widget 中通過InheritedWidget共享了一個(gè)數(shù)據(jù)晓猛,那么我們便可以在任意子widget 中來獲取該共享的數(shù)據(jù)德绿!這個(gè)特性在一些需要在整個(gè) widget 樹中共享數(shù)據(jù)的場(chǎng)景中非常方便忱叭!如Flutter SDK中正是通過 InheritedWidget 來共享應(yīng)用主題(Theme)和 Locale (當(dāng)前語言環(huán)境)信息的碉考。
InheritedWidget和 React 中的 context 功能類似占锯,和逐級(jí)傳遞數(shù)據(jù)相比袒哥,它們能實(shí)現(xiàn)組件跨級(jí)傳遞數(shù)據(jù)。InheritedWidget的在 widget 樹中數(shù)據(jù)傳遞方向是從上到下的消略,這和通知Notification(將在下一章中介紹)的傳遞方向正好相反堡称。
下面我們看一下之前“計(jì)數(shù)器”示例應(yīng)用程序的InheritedWidget版本。需要說明的是艺演,本示例主要是為了演示InheritedWidget的功能特性却紧,并不是計(jì)數(shù)器的推薦實(shí)現(xiàn)方式桐臊。
首先,我們通過繼承InheritedWidget晓殊,將當(dāng)前計(jì)數(shù)器點(diǎn)擊次數(shù)保存在ShareDataWidget的data屬性中:
class ShareDataWidget extends InheritedWidget {
ShareDataWidget({
Key? key,
required this.data,
required Widget child,
}) : super(key: key, child: child);
final int data; //需要在子樹中共享的數(shù)據(jù)断凶,保存點(diǎn)擊次數(shù)
//定義一個(gè)便捷方法,方便子樹中的widget獲取共享數(shù)據(jù)
static ShareDataWidget? of(BuildContext context) {
return context.dependOnInheritedWidgetOfExactType<ShareDataWidget>();
}
//該回調(diào)決定當(dāng)data發(fā)生變化時(shí)巫俺,是否通知子樹中依賴data的Widget重新build
@override
bool updateShouldNotify(ShareDataWidget old) {
return old.data != data;
}
}
然后我們實(shí)現(xiàn)一個(gè)子組件_TestWidget认烁,在其build方法中引用ShareDataWidget中的數(shù)據(jù)。同時(shí)介汹,在其didChangeDependencies() 回調(diào)中打印日志:
2. didChangeDependencies
在之前介紹StatefulWidget時(shí)却嗡,我們提到State對(duì)象有一個(gè)didChangeDependencies回調(diào),它會(huì)在“依賴”發(fā)生變化時(shí)被Flutter 框架調(diào)用痴昧。而這個(gè)“依賴”指的就是子 widget 是否使用了父 widget 中InheritedWidget的數(shù)據(jù)稽穆!如果使用了,則代表子 widget 有依賴赶撰;如果沒有使用則代表沒有依賴舌镶。這種機(jī)制可以使子組件在所依賴的InheritedWidget變化時(shí)來更新自身!比如當(dāng)主題豪娜、locale(語言)等發(fā)生變化時(shí)餐胀,依賴其的子 widget 的didChangeDependencies方法將會(huì)被調(diào)用.