Flutter最大難點---狀態(tài)管理吕粹,解決了,就可以大膽擼Flutter App了

為什么需要狀態(tài)管理岗仑?

剛開始構(gòu)建應(yīng)用的時候匹耕,只有少許狀態(tài)需要管理,這時候可能并不需要狀態(tài)管理荠雕。

但隨著功能增加稳其,會出現(xiàn)成百上千的狀態(tài),如果沒有狀態(tài)管理炸卑,就會亂成一鍋粥既鞠。

Provide是借助inheritWidget ,把共享狀態(tài)放到頂層materialApp之上,底層部件通過provider獲取該狀態(tài)盖文,并通過混合ChangeNotifier通知依賴于該狀態(tài)的組件刷新嘱蛋。Provide還提供了Provide.stream,讓我們能夠以處理流的方式處理數(shù)據(jù)。

開始吧洒敏!

這兩個頁面都同時依賴于counter 和 switcher兩個不同的狀態(tài)龄恋。并且一個頁面改變狀態(tài)之后另外一個頁面狀態(tài)也隨之改變。

該項目完整代碼已放在?Github

第一步:添加依賴

在pubspec.yaml中添加Provide的依賴桐玻。

provide : ^1.0.1? #這里版本查看官方

實際添加請參考:pub.dartlang.org/packages/pr…

由于版本沖突添加失敗請參考:?juejin.im/post/5b8958…?

import 'package:provide/provide.dart';

第二步篙挽,創(chuàng)建Model

這里實際上它承擔(dān)了State的職責(zé),但是為了和官方的State區(qū)分所以叫做model镊靴。?

這里以簡單的Counter為例:

對比Scoped_m這里我們可以看到铣卡,數(shù)據(jù)和操作數(shù)據(jù)的方法都在model中,我們可以很清晰的把業(yè)務(wù)分離出來偏竟。這里我們可以發(fā)現(xiàn)煮落,Provide模式中model不再需要繼承Model類,只需要實現(xiàn)Listenable踊谋,我們這里混入ChangeNotifier蝉仇,可以不用管理聽眾。

第三步:將狀態(tài)放入頂層?? 這里雖然定義在全局,但事實上也可以定義在頁面級

ProviderNode表示的是提供者

ProviderNode封裝了InheritWidget殖蚕,并且提供了 一個providers容器用于放置狀態(tài)轿衔。

ProviderScope 為Provider提供單獨的類型空間,它允許多個相同類型的提供者睦疫。默認使用ProviderScope('_default'),存放的時候你可以通過ProviderScope("name")來指定key害驹。

添加一組Provider的時候建議使用provideFrom或者provide方法,而不是provideAll蛤育,因為它可以檢查編譯時的類型錯誤宛官。?

Provider.value將counter包裝成了_ValueProvider。并在它的內(nèi)部提供了StreamController從而實現(xiàn)對數(shù)據(jù)進行流式操作瓦糕。?

第四步底洗,獲取狀態(tài)

一,同樣的Provide也提供了兩種獲取State的方法咕娄。我們先來介紹第一種亥揖,通過Provide小部件獲取。

每次通知數(shù)據(jù)刷新時圣勒,builder將會重新構(gòu)建這個小部件费变。builder方法接收三個參數(shù),這里主要介紹第二個和第三個灾而。第二個參數(shù)child:假如這個小部件足夠復(fù)雜胡控,內(nèi)部有一些小部件是不會改變的,那么我們可以將這部分小部件寫在Provide的child屬性中旁趟,讓builder不再重復(fù)創(chuàng)建這些小部件昼激,以提升性能庇绽。第三個參數(shù)counter:這個參數(shù)代表了我們獲取的頂層providers中的狀態(tài)。scope:通過指定ProviderScope獲取該鍵所對應(yīng)的狀態(tài)橙困。在需要使用多個相同類型狀態(tài)的時候使用瞧掺。

二,第二種獲取方式:Provide.value<T>(context)

這種方式實際上調(diào)用了context.inheritFromWidgetOfExactType找到頂層的_InheritedProviders來獲取到頂層providers中的狀態(tài)凡傅。

添加一個方法,用于獲取Counter實例:

Provide會在Counter發(fā)生變化的時候,觸發(fā)builder回調(diào)來更新界面

發(fā)通知

第五步:如何組織多個狀態(tài)

provide模式中你可以輕松組織多個狀態(tài)辟狈。只需要將狀態(tài)provide放進provider中就可以了。

第六步夏跷,獲取數(shù)據(jù)流

在將counter添加進providers的過程中進行了一次包裝哼转。我們剛才通過分析源碼知道了這個操作能夠讓我們處理流式數(shù)據(jù)。

通過 Provide.stream<T>(context) 就能獲取數(shù)據(jù)流槽华。需要注意的是壹蔓,這里每次獲取的數(shù)據(jù)流都如下:

不過在我的使用當中出現(xiàn)了streamTransformer失效的情況。在firstScreen和secondScreen同樣應(yīng)用這一段相同的代碼猫态,second screen的where方法能夠生效佣蓉,過濾掉奇數(shù)數(shù)據(jù),而first screen中則是收到了完整的數(shù)據(jù)亲雪。

需要注意的是勇凭,這里每次獲取的數(shù)據(jù)流都會重新創(chuàng)建一條新的流。

關(guān)于這個做法還有一些爭議义辕,具體可以查看這個issue:

github.com/google/flut…

不過這個功能還可以結(jié)合rxdart使用虾标,可以通過stream輕松構(gòu)建Observer,讓我們更加靈活的組織數(shù)據(jù)终息。

第七步夺巩,根據(jù)多個狀態(tài)重建小部件

當我們一個視圖可能依賴于多個狀態(tài)進行重建的時候贞让,可以使用ProvideMulti小部件周崭。

第八步,可能出現(xiàn)的問題

由于 Provide 自動將 Listenable 數(shù)據(jù)包裝并提供了 Provide.stream 接口喳张,讓我們可以通過監(jiān)聽這個流续镇,來獲取最新事件。但是當我們進行手動監(jiān)聽之后將會發(fā)生這件詭異的事情销部。


按理說這里應(yīng)該在數(shù)據(jù)發(fā)生變化的時候收到一條事件摸航,可是我們這里發(fā)現(xiàn)一次性輸出了 5 條flutter: Instance of 'Switcher'

為什么是 5 條呢舅桩,這是因為我一共在 5 處 地方收聽過這個數(shù)據(jù)酱虎,包括使用 Provide Widget 也算一次收聽。

而當我退出第二個頁面之后再次進入擂涛,發(fā)現(xiàn)這次收到的數(shù)據(jù)比上次多了 5 條读串。

出現(xiàn)這個現(xiàn)象是由于這個 stream 是由工廠方法創(chuàng)建,每次調(diào)用 Provide.stream 都會重新創(chuàng)建出來一條流。就算收聽者不再收聽恢暖,這條流也會存在排监。

所以不要去手動監(jiān)聽你的 Provide.stream。

Stream模式

stream是使用Provide.stream<Counter>(context)獲取的

在provide中有一個概念叫scope,類的完整類名叫ProviderScope

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末杰捂,一起剝皮案震驚了整個濱河市舆床,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌嫁佳,老刑警劉巖挨队,帶你破解...
    沈念sama閱讀 206,214評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異蒿往,居然都是意外死亡瞒瘸,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,307評論 2 382
  • 文/潘曉璐 我一進店門熄浓,熙熙樓的掌柜王于貴愁眉苦臉地迎上來情臭,“玉大人,你說我怎么就攤上這事赌蔑「┰冢” “怎么了?”我有些...
    開封第一講書人閱讀 152,543評論 0 341
  • 文/不壞的土叔 我叫張陵娃惯,是天一觀的道長跷乐。 經(jīng)常有香客問我,道長趾浅,這世上最難降的妖魔是什么愕提? 我笑而不...
    開封第一講書人閱讀 55,221評論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮皿哨,結(jié)果婚禮上浅侨,老公的妹妹穿的比我還像新娘。我一直安慰自己证膨,他們只是感情好如输,可當我...
    茶點故事閱讀 64,224評論 5 371
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著央勒,像睡著了一般不见。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上崔步,一...
    開封第一講書人閱讀 49,007評論 1 284
  • 那天稳吮,我揣著相機與錄音,去河邊找鬼井濒。 笑死灶似,一個胖子當著我的面吹牛慎陵,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播喻奥,決...
    沈念sama閱讀 38,313評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼席纽,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了撞蚕?” 一聲冷哼從身側(cè)響起润梯,我...
    開封第一講書人閱讀 36,956評論 0 259
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎甥厦,沒想到半個月后纺铭,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,441評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡刀疙,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,925評論 2 323
  • 正文 我和宋清朗相戀三年舶赔,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片谦秧。...
    茶點故事閱讀 38,018評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡竟纳,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出疚鲤,到底是詐尸還是另有隱情锥累,我是刑警寧澤,帶...
    沈念sama閱讀 33,685評論 4 322
  • 正文 年R本政府宣布集歇,位于F島的核電站桶略,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏诲宇。R本人自食惡果不足惜际歼,卻給世界環(huán)境...
    茶點故事閱讀 39,234評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望姑蓝。 院中可真熱鬧鹅心,春花似錦、人聲如沸它掂。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,240評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽虐秋。三九已至,卻和暖如春垃沦,著一層夾襖步出監(jiān)牢的瞬間客给,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,464評論 1 261
  • 我被黑心中介騙來泰國打工肢簿, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留靶剑,地道東北人蜻拨。 一個月前我還...
    沈念sama閱讀 45,467評論 2 352
  • 正文 我出身青樓,卻偏偏與公主長得像桩引,于是被迫代替她去往敵國和親缎讼。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 42,762評論 2 345

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

  • 該文已授權(quán)公眾號 「碼個蛋」,轉(zhuǎn)載請指明出處講了那么多的部件厘灼,這節(jié)我打算來點不太一樣的夹纫,可能會沒有部件那么好理解,...
    Kuky_xs閱讀 4,906評論 7 25
  • 前言 今天偶然發(fā)現(xiàn)在谷歌爸爸的倉庫下出現(xiàn)了一個叫做flutter-provide的狀態(tài)管理框架设凹,2月8日才第一次提...
    Vadaski閱讀 19,751評論 12 39
  • 如何吸引你的讀者 一個好故事的第一標準是什么舰讹? 優(yōu)美的文筆,哲理的話語闪朱,美麗的風(fēng)景描寫月匣,人物內(nèi)心的精妙獨白,還是奋姿?...
    羅小宸閱讀 617評論 3 6
  • 今晚洗完澡出來用舊手機聽歌的時候無意間點到微信看到之前聊天時你給我發(fā)的語音桶错,我特別欣喜地點開,以為你復(fù)我了...
    ClaireZ閱讀 207評論 0 0
  • 已有兩天沒有更文了胀蛮,上次聊的是女人每日必須要做皮膚護理院刁,皮膚護理最重要的是基底護理,基底護理相當是蓋一棟樓要打好地...
    5b2369f0dc1b閱讀 664評論 0 1