InheritedWidget使用說(shuō)明

InheritedWidget

概述

在Flutter進(jìn)行界面開(kāi)發(fā)時(shí),我們經(jīng)常會(huì)遇到數(shù)據(jù)傳遞的問(wèn)題惩阶。由于Flutter采用節(jié)點(diǎn)樹(shù)的方式組織頁(yè)面,以致于一個(gè)普通頁(yè)面的節(jié)點(diǎn)層級(jí)會(huì)很深扣汪。此時(shí)断楷,我們?nèi)绻€是一層層傳遞數(shù)據(jù),當(dāng)需要修改數(shù)據(jù)時(shí)崭别,就會(huì)比較麻煩冬筒。

此時(shí),我們需要一種機(jī)制茅主,能夠讓某一個(gè)節(jié)點(diǎn)下的所有子節(jié)點(diǎn)舞痰,訪問(wèn)該節(jié)點(diǎn)下的數(shù)據(jù)。

InheritedWidget就滿足了我們這一需求诀姚。

使用方法

我們創(chuàng)建一個(gè)繼承InheritedWidget的Widget响牛。

class MyInheritedWidget extends InheritedWidget {
  final int data;

  MyInheritedWidget(@required this.data, Widget child) : super(child: child);

  static MyInheritedWidget getData(BuildContext context) {
    return context.inheritFromWidgetOfExactType(MyInheritedWidget);
  }


  @override
  bool updateShouldNotify(MyInheritedWidget oldWidget) {
    return oldWidget.data != data;
  }


}

可以看到,我們提供了三個(gè)方法赫段。

構(gòu)造方法

InheritedWidget本身是一個(gè)沒(méi)有界面的Widget娃善,或者說(shuō)是一個(gè)代理Widget,我們需要傳入我們實(shí)際的Widget瑞佩。

所以聚磺,在構(gòu)造方法中,我們需要傳入兩個(gè)參數(shù)炬丸,一個(gè)是我們希望共享的數(shù)據(jù)(在本例中數(shù)據(jù)是int型瘫寝,實(shí)際業(yè)務(wù)中共享的通常是一個(gè)相對(duì)復(fù)雜的數(shù)據(jù))蜒蕾,另一個(gè)就是我們帶界面的Widget。

數(shù)據(jù)獲取方法

  static MyInheritedWidget getData(BuildContext context) {
    return context.inheritFromWidgetOfExactType(MyInheritedWidget);
  }

我們看一下inheritFromWidgetOfExactType方法的源碼:

  /// Obtains the nearest widget of the given type, which must be the type of a
  /// concrete [InheritedWidget] subclass, and registers this build context with
  /// that widget such that when that widget changes (or a new widget of that
  /// type is introduced, or the widget goes away), this build context is
  /// rebuilt so that it can obtain new values from that widget.
  
  /// The [aspect] parameter is only used when [targetType] is an
  /// [InheritedWidget] subclasses that supports partial updates, like
  /// [InheritedModel]. It specifies what "aspect" of the inherited
  /// widget this context depends on.
  InheritedWidget inheritFromWidgetOfExactType(Type targetType, { Object aspect });
  

注釋說(shuō)得很清楚焕阿,inheritFromWidgetOfExactType是獲取指定context下的咪啡,最近的指定類(lèi)型的Widget,并且此Widget必須是InheritedWidget的子類(lèi)暮屡。

值得注意的是撤摸,它是一個(gè)靜態(tài)方法。所以褒纲,只要是相同BuildContext我們即可以在任意子節(jié)點(diǎn)上准夷,通過(guò)這個(gè)靜態(tài)方法,獲取到我們的InheritedWidget莺掠,然后讀取或修改它的共享數(shù)據(jù)衫嵌。

更新通知

這個(gè)方法,決定了是否通知子節(jié)點(diǎn)中StatefulWidgetdidChangeDependencies方法是否調(diào)用彻秆。

  /// Called when a dependency of this [State] object changes.
  ///
  /// For example, if the previous call to [build] referenced an
  /// [InheritedWidget] that later changed, the framework would call this
  /// method to notify this object about the change.
  ///
  /// This method is also called immediately after [initState]. It is safe to
  /// call [BuildContext.inheritFromWidgetOfExactType] from this method.
  ///
  /// 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() { }

StatefulWidget的didChangeDependencies方法就是與InheritedWidget配合使用的楔绞。只有當(dāng)InheritedWidget發(fā)生更新并且決定通知時(shí),didChangeDependencies才會(huì)調(diào)用唇兑。

使用場(chǎng)景

通常酒朵,當(dāng)我們需要在Widget樹(shù),由父節(jié)點(diǎn)向子節(jié)點(diǎn)傳遞數(shù)據(jù)時(shí)扎附,會(huì)使用InheritedWidget耻讽。一旦某個(gè)節(jié)點(diǎn)的Widget繼承了InheritedWidget,那么它的子節(jié)點(diǎn)帕棉,不論深度是多少针肥,都可以獲取到繼承了InheritedWidget的Widget,并取得其中的數(shù)據(jù)成員香伴。

class TextWidget extends StatefulWidget {
  @override
  State<StatefulWidget> createState() {
    return TextWidgetState();
  }

}

class TextWidgetState extends State<TextWidget> {
  @override
  Widget build(BuildContext context) {
    print("refresh text");
    return Text(
        "count : ${MyInheritedWidget.getData(context).data}"
    );
  }

  @override
  void didChangeDependencies() {
    super.didChangeDependencies();
    //父或祖先widget中的InheritedWidget改變(updateShouldNotify返回true)時(shí)會(huì)被調(diào)用慰枕。
    //如果build中沒(méi)有依賴(lài)InheritedWidget,則此回調(diào)不會(huì)被調(diào)用即纲。
    print("Dependencies change");
  }

}

所以具帮,InheritedWidget適合做某個(gè)子樹(shù)的數(shù)據(jù)管理Widget。當(dāng)某個(gè)頁(yè)面低斋、模塊或控件依賴(lài)一個(gè)或一組數(shù)據(jù)時(shí)蜂厅。我們可以在其上層,創(chuàng)建一個(gè)繼承了InheritedWidget的數(shù)據(jù)管理Widget膊畴。

通過(guò)這樣的方式掘猿,至少我們不用對(duì)數(shù)據(jù)進(jìn)行層層傳遞。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末唇跨,一起剝皮案震驚了整個(gè)濱河市稠通,隨后出現(xiàn)的幾起案子衬衬,更是在濱河造成了極大的恐慌,老刑警劉巖改橘,帶你破解...
    沈念sama閱讀 216,372評(píng)論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件滋尉,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡飞主,警方通過(guò)查閱死者的電腦和手機(jī)狮惜,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,368評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)碌识,“玉大人碾篡,你說(shuō)我怎么就攤上這事⊥杳幔” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 162,415評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵薛窥,是天一觀的道長(zhǎng)胖烛。 經(jīng)常有香客問(wèn)我,道長(zhǎng)诅迷,這世上最難降的妖魔是什么佩番? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,157評(píng)論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮罢杉,結(jié)果婚禮上趟畏,老公的妹妹穿的比我還像新娘。我一直安慰自己滩租,他們只是感情好赋秀,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,171評(píng)論 6 388
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著律想,像睡著了一般猎莲。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上技即,一...
    開(kāi)封第一講書(shū)人閱讀 51,125評(píng)論 1 297
  • 那天著洼,我揣著相機(jī)與錄音,去河邊找鬼而叼。 笑死身笤,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的葵陵。 我是一名探鬼主播液荸,決...
    沈念sama閱讀 40,028評(píng)論 3 417
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼脱篙!你這毒婦竟也來(lái)了莹弊?” 一聲冷哼從身側(cè)響起涤久,我...
    開(kāi)封第一講書(shū)人閱讀 38,887評(píng)論 0 274
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎忍弛,沒(méi)想到半個(gè)月后响迂,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,310評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡细疚,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,533評(píng)論 2 332
  • 正文 我和宋清朗相戀三年蔗彤,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片疯兼。...
    茶點(diǎn)故事閱讀 39,690評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡然遏,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出吧彪,到底是詐尸還是另有隱情待侵,我是刑警寧澤,帶...
    沈念sama閱讀 35,411評(píng)論 5 343
  • 正文 年R本政府宣布姨裸,位于F島的核電站秧倾,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏傀缩。R本人自食惡果不足惜那先,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,004評(píng)論 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望赡艰。 院中可真熱鬧售淡,春花似錦、人聲如沸慷垮。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,659評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)料身。三九已至楔壤,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間惯驼,已是汗流浹背蹲嚣。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,812評(píng)論 1 268
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留祟牲,地道東北人隙畜。 一個(gè)月前我還...
    沈念sama閱讀 47,693評(píng)論 2 368
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像说贝,于是被迫代替她去往敵國(guó)和親议惰。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,577評(píng)論 2 353

推薦閱讀更多精彩內(nèi)容

  • 首先乡恕,在Flutter中幾乎所有的對(duì)象都是一個(gè)Widget言询。跟原生開(kāi)發(fā)中的“控件”不同俯萎,F(xiàn)lutter中的Widg...
    沉江小魚(yú)閱讀 1,643評(píng)論 0 2
  • 1.前言 本文涵蓋了Widget,State运杭,BuildContext夫啊,InheritedWidget等術(shù)語(yǔ)的相關(guān)...
    巧巧的二表哥閱讀 2,607評(píng)論 0 5
  • 原文在此,此處只為學(xué)習(xí) Widget與ElementWidget主要接口Stateless WidgetState...
    lltree閱讀 4,510評(píng)論 0 1
  • 概念 在前面的介紹中辆憔,我們知道在Flutter中幾乎所有的對(duì)象都是一個(gè)Widget撇眯。與原生開(kāi)發(fā)中“控件”不同的是,...
    小小的開(kāi)發(fā)人員閱讀 635評(píng)論 0 2
  • 1 Widget只是UI元素的一個(gè)配置數(shù)據(jù)虱咧,并且一個(gè)Widget可以對(duì)應(yīng)多個(gè)ElementWidget實(shí)際上就是E...
    你飛躍俊杰閱讀 728評(píng)論 0 2