阅读 2245

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

今天来介绍下Flutter中BLoC的原理及使用场景,有兴趣的建议先耐心看完文章,相信还是能收获一些东西的~ ^_^


介绍BLoC之前,先介绍几个相关的类及概念:

前提概述

Stream流种类

  1. 单订阅流:只能有一个订阅者
  2. 多订阅流:可以多个订阅者,订阅前的消息不会收到

单订阅->多订阅:stream.asBroadcastStream()

StreamBuilder API

使用Stream来构造UI,具体参考文档中的视频。

StreamController的使用方式

下图是整个StreamController的工作方式

从sink.add传入值,对应输出stream流,可以做相应的流变换,然后对应监听此流的地方将接受到数据。

RxDart

用于通过使用可观察序列来编写异步和基于事件的程序,具体文档参考:RxDart

增强版StreamController:

  1. PublishSubject: 普通广播的streamcontroll,可监听多次(默认异步)
  2. BehaviorSubject: 缓存最新一次事件的广播流控制器
  3. 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实现此设计模式,需要用到:

  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来实现的。


如有问题欢迎指正~~