圖解Flutter——BLoC的原理及使用

今天來介紹下Flutter中BLoC的原理及使用場景,有興趣的建議先耐心看完文章,相信仍是能收穫一些東西的~ ^_^html


介紹BLoC以前,先介紹幾個相關的類及概念:react

前提概述

Stream流種類

  1. 單訂閱流:只能有一個訂閱者
  2. 多訂閱流:能夠多個訂閱者,訂閱前的消息不會收到

單訂閱->多訂閱:stream.asBroadcastStream()git

StreamBuilder API

使用Stream來構造UI,具體參考文檔中的視頻。github

StreamController的使用方式

下圖是整個StreamController的工做方式設計模式

從sink.add傳入值,對應輸出stream流,能夠作相應的流變換,而後對應監聽此流的地方將接受到數據。api

RxDart

用於經過使用可觀察序列來編寫異步和基於事件的程序,具體文檔參考:RxDart緩存

加強版StreamController:markdown

  1. PublishSubject: 普通廣播的streamcontroll,可監聽屢次(默認異步)
  2. BehaviorSubject: 緩存最新一次事件的廣播流控制器
  3. ReplaySubject : 緩存多個數據的廣播流控制器,能夠設定上限

每一個xxSubject能夠當作一個單元(後面備用): 異步

Observable:可觀察對象, 擴展Stream,組合了Streams和StreamTransformers(默認單一訂閱)async

InheritedWidget

下面是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:Business Logic Component (業務邏輯組件)

BLoC是一個典型的觀察者模式

Flutter實現此設計模式,須要用到:

  1. BlocProvider組件:InheritedWidget 繼承組件 + Bloc對象
  2. Bloc類: Stream(dart)/ Subject(rxdart stream)

BlocProvider

BLoC類的幾種用法及對應使用場景

Type1:最基本的初始化及使用

下圖是對應Bloc的內部實現:

Type2: 事件轉化State的方式:

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);
      }
  }
複製代碼
Type3:註冊、登陸校驗

PS: Mixin 爲bloc類增長了兩個功能,根據輸入流,進行相應的校驗郵箱和密碼是否符合要求

Type4:購物列表實現

上圖是有一個購物車列表頁pageBloc 和 購物車裏面的商品itemBloc組成 經過商品item的+-,事件流向到pageBloc, 監聽pageBloc變化的紅點數據進行相應變化 同時監聽pageBloc的itemBloc進行判斷是否在購物車進行返回對應bool值,標識是否在購物車 最後進行更新對應item的狀態,變成+-號。

具體代碼參考: ShopItemBloc


文尾: 以上相應的4種場景是從一個國外大牛文章總結出來的,文章比較長,讀起來可能比較累,若是結合個人總結來閱讀,相信應該能夠很快的理解。

文章地址: Reactive Programming - Streams - BLoC - Practical Use Cases 目前項目中用的是: flutter_bloc 也是這位大神寫的,基本上能夠知足平時的業務需求。

另外,最新的BlocProvider是基於Provider來實現的。


若有問題歡迎指正~~

相關文章
相關標籤/搜索