今天來介紹下Flutter中BLoC的原理及使用場景,有興趣的建議先耐心看完文章,相信還是能收穫一些東西的~ ^_^
介紹BLoC之前,先介紹幾個相關的類及概念:
前提概述
Stream流種類
- 單訂閱流:只能有一個訂閱者
- 多訂閱流:可以多個訂閱者,訂閱前的訊息不會收到
單訂閱->多訂閱:stream.asBroadcastStream()
StreamBuilder API
使用Stream來構造UI,具體參考文件中的視訊。
StreamController的使用方式
下圖是整個StreamController的工作方式
從sink.add傳入值,對應輸出stream流,可以做相應的流變換,然後對應監聽此流的地方將接受到資料。
RxDart
用於通過使用可觀察序列來編寫非同步和基於事件的程式,具體文件參考:RxDart
增強版StreamController:
PublishSubject
: 普通廣播的streamcontroll,可監聽多次(預設非同步)BehaviorSubject
: 快取最新一次事件的廣播流控制器ReplaySubject
: 快取多個資料的廣播流控制器,可以設定上限
每個xxSubject可以看成一個單元(後面備用):
Observable
:可觀察物件, 擴充套件Stream,組合了Streams和StreamTransformers(預設單一訂閱)
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實現此設計模式,需要用到:
- BlocProvider元件:InheritedWidget 繼承元件 + Bloc物件
- 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來實現的。
如有問題歡迎指正~~