今天来介绍下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来实现的。
若有问题欢迎指正~~