Flutter-狀態管理(scoped_model)

Flutter是一款響應式的UI框架,其中設計靈感很多來源于React.同React一樣,它將數據與視圖分離,由數據作為驅動去映射渲染視圖.so,也將widget分為Stateless widgetsStateful widgets

  • StatelessWidget: 是不可變的, 它是無狀態的,這意味著這些控件的屬性不能改變,是靜態的,就是我們常說的寫死的頁面.
  • StatefulWidget: 持有的狀態,是動態頁面.它會隨狀態的改變而重新渲染自己本身.(StatefulWidget類本身是不變的,起作用的是State類,它在widget生命周期中始終存在的.)

實現一個有狀態的頁面如下:

// 1.繼承StatefulWidget,并實現其createState()方法,與自己的state綁定.
class HomePage extends StatefulWidget {
@override
_HomePageState createState() {
  return new _HomePageState();
}
}

//2繼續State,并實現其build()方法創建自己UI視圖,通過調用setState方法去觸發視圖的渲染更新
class _HomePageState extends State<HomePage>{
  @override
  void initState() {
      super.initState();
}

  @override
Widget build(BuildContext context) {
  return SingleChildScrollView(
    child: Column(
      children: ContentLayout(),
    ),
  )
}
}

實現一個擁有狀態的頁面至少需要實現其兩個類.你可能會意識到,隨著功能的增加,頁面的累積,會出現越來越多的狀態頁面,而且還會有多個頁面共享同一個狀態,導致代碼抒寫過于冗余和復雜.這時候,基于迫切的需要,狀態管理框架應運而生。

scoped_model
用于管理狀態的框架.官方文檔介紹中寫道,它可以輕松將數據模型從父級widget傳入它的children,并且當數據模型發生改變時,會自發的更新所有使用她的wigdet.現在來簡單講解下它的用法.

這里有三個主要用到的類:

  • Model 如名,定義數據的類,將你要數據定義在一個類并繼承于它,類中有個notifyListeners(),用于刷新與它關聯的widgets.
import 'package:scoped_model/scoped_model.dart';

class CounterModel extends Model {
  int _counter = 0;

  int get counter => _counter;

  void increment() {
    // First, increment the counter
    _counter++;

    // Then notify all the listeners.
    notifyListeners();
  }
}
  • ScopedModel 它其實是個widget,繼承于StatelessWidget類.它主要接收兩個參數:model(數據模型)和child(會使用到這個數據模型對應的widget).

  • ScopedModelDescendant 它也繼承于StatelessWidget,使用此widget,其包含的子wigets可以找到對應的ScopedModel,它可以獲取與ScopedModel綁定的數據模型,且當數據模型發送改變時,它將自動重新構建渲染.說白了,它主要功能就是讓子頁面能夠獲取到model即數據~

class CounterApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new ScopedModel<CounterModel>(
        model: new CounterModel(),
        child: new Column(children: [
          // Create a ScopedModelDescendant. This widget will get the
          // CounterModel from the nearest ScopedModel<CounterModel>.
          // It will hand that model to our builder method, and rebuild
          // any time the CounterModel changes (i.e. after we
          // `notifyListeners` in the Model).
          new ScopedModelDescendant<CounterModel>(
            builder: (context, child, model) => new Text('${model.counter}'),
          ),
          new Text("Another widget that doesn't depend on the CounterModel")
        ])
    );
  }
}

當然還有另一種方法獲取到Model:

final countModel = ScopedModel.of<CountModel>(context);

然后這里我也有個比較疑惑的地方,就是當一個widet需要使用多個Model時,參考官方文檔講解(https://pub.dartlang.org/packages/scoped_model):

    1. Use multiple ScopedModelDescendant Widgets
    1. Use multiple ScopedModel.of calls. No need to manage subscriptions, Flutter takes care of all of that through the magic of InheritedWidgets.
class CombinedWidget extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    final username =
      ScopedModel.of<UserModel>(context, rebuildOnChange: true).username;
    final counter =
      ScopedModel.of<CounterModel>(context, rebuildOnChange: true).counter;

    return Text('$username tapped the button $counter times');
  }
}

當是我在看ScopedModel 和ScopedModelDescendant 源碼時,類中并有提供接受多個model的構造方法. 然后參考https://juejin.im/post/5b97fa0d5188255c5546dcf8 , 是指Model 使用使用Mixin進行多繼承,但這必定帶來很多耦合

(如果有說的不當的,也請大佬賜教~共同交流,共同進步!)

?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,505評論 6 533
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,556評論 3 418
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,463評論 0 376
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,009評論 1 312
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,778評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,218評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,281評論 3 441
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,436評論 0 288
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,969評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,795評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,993評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,537評論 5 359
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,229評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,659評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,917評論 1 286
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,687評論 3 392
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,990評論 2 374

推薦閱讀更多精彩內容

  • 前言 Flutter的很多靈感來自于React,它的設計思想是數據與視圖分離,由數據映射渲染視圖。所以在Flutt...
    Vadaski閱讀 11,768評論 11 27
  • 原文在此,此處只為學習 Widget與ElementWidget主要接口Stateless WidgetState...
    lltree閱讀 4,525評論 0 1
  • 本文主要介紹了Flutter布局相關的內容,對相關知識點進行了梳理,并從實際例子觸發,進一步講解該如何去進行布局。...
    Q吹個大氣球Q閱讀 9,851評論 6 51
  • 心底的佛號 總被忐忑的時鐘打斷 妄想永遠遮著前路 忽隱忽現 而身后 卻綴滿一個個 大寫的感嘆 粗重的喘息 砸在日歷...
    文曦原創閱讀 197評論 0 0
  • 在康定,在滄州,在撫順,這一刻他們在干嘛呢 喝咖啡嗎,嘮嗑嗎,做菜嗎,或者,發著呆嗎 感覺許久未曾聯系他們,朋友圈...
    陶一一閱讀 265評論 0 0