今天來介紹下Flutter中BLoC的原理及使用場景,有興趣的建議先耐心看完文章,相信仍是能收穫一些東西的~ ^_^html
介紹BLoC以前,先介紹幾個相關的類及概念:react
單訂閱->多訂閱:stream.asBroadcastStream()git
使用Stream來構造UI,具體參考文檔中的視頻。github
下圖是整個StreamController的工做方式設計模式
從sink.add傳入值,對應輸出stream流,能夠作相應的流變換,而後對應監聽此流的地方將接受到數據。api
用於經過使用可觀察序列來編寫異步和基於事件的程序,具體文檔參考:RxDart緩存
加強版StreamController:markdown
PublishSubject
: 普通廣播的streamcontroll,可監聽屢次(默認異步)BehaviorSubject
: 緩存最新一次事件的廣播流控制器ReplaySubject
: 緩存多個數據的廣播流控制器,能夠設定上限每一個xxSubject能夠當作一個單元(後面備用): 異步
Observable
:可觀察對象, 擴展Stream,組合了Streams和StreamTransformers(默認單一訂閱)async
下面是InheritedWidget的工做方式:
Static T of(BuildContext context) => context.inheritFromWidgetOfExactType(T);
final t = T.of(context)
上面的怎麼使用呢?在Child組件中:
Root root = Root.of(context);//獲取Root對象 root.data... // 使用root對象的變量等 複製代碼
接下來切入正題:
BLoC是一個典型的觀察者模式
Flutter實現此設計模式,須要用到:
Event->State (狀態轉化圖)
簡單解讀下: 此轉化的原理是,經過發送一個event,通過一個普通廣播PublishSubject, 到達中間監聽處理器:eventHandler,做用是根據得到到的event作相應的異步處理,處理結束後,轉化出一些相應的state返回出來 將返回的結果所有add到下來的BehaviorSubject中,因爲BehaviorSubject的特性,傳遞並保留最新的一條結果。 UI監聽到對應的state,而後作出不一樣的界面相應便可。
舉個小栗子:經常使用的加載數據的場景
下面是手寫的Bloc中部分代碼,僅供邏輯參考:
Stream<AbstractState> eventHandler(AbstractEvent event) async* { if (event is InitEvent) { yield LoadingState(); final remoteData = await Request.fetchData(); yield ResultData(remoteData); } else if (event is RefreshState) { final remoteData = await Request.fetchData(); yield UpdateData(remoteData); } } 複製代碼
PS: Mixin 爲bloc類增長了兩個功能,根據輸入流,進行相應的校驗郵箱和密碼是否符合要求
上圖是有一個購物車列表頁pageBloc 和 購物車裏面的商品itemBloc組成 經過商品item的+-,事件流向到pageBloc, 監聽pageBloc變化的紅點數據進行相應變化 同時監聽pageBloc的itemBloc進行判斷是否在購物車進行返回對應bool值,標識是否在購物車 最後進行更新對應item的狀態,變成+-號。
具體代碼參考: ShopItemBloc
文尾: 以上相應的4種場景是從一個國外大牛文章總結出來的,文章比較長,讀起來可能比較累,若是結合個人總結來閱讀,相信應該能夠很快的理解。
文章地址: Reactive Programming - Streams - BLoC - Practical Use Cases 目前項目中用的是: flutter_bloc 也是這位大神寫的,基本上能夠知足平時的業務需求。
另外,最新的BlocProvider是基於Provider來實現的。
若有問題歡迎指正~~