Flutter 开发实战

235课时
1K学过
8分

课程评价 (0)

请对课程作出评价:
0/300

学员评价

暂无精选评价
2分钟

04 BloC

BloC 全称 Business Logic Component ,它属于一种设计模式,在 Flutter 中它主要是通过 StreamSteamBuilder 来实现设计的,所以 BloC 实现起来也相对简单,关于 StreamSteamBuilder 的实现原理可以查看前篇,这里主要展示如何完成一个简单的 BloC

如下代码所示,整个流程总结为:

  • 定义一个 PageBloc 对象,利用 StreamController 创建 SinkStream
  • PageBloc 对外暴露 Stream 用来与 StreamBuilder 结合;暴露 add 方法提供外部调用,内部通过 Sink 更新 Stream
  • 利用 StreamBuilder 加载监听 Stream 数据流,通过 snapShot 中的 data 更新控件。

当然,如果和 rxdart 结合可以简化 StreamController 的一些操作,同时如果你需要利用 BloC模式实现状态共享,那么自己也可以封装多一层 InheritedWidgets 的嵌套,如果对于这一块有疑惑的话,推荐可以去看看上一篇的 Stream 解析。

class _BlocPageState extends State<BlocPage> {
  final PageBloc _pageBloc = new PageBloc();
  @override
  void dispose() {
    _pageBloc.dispose();
    super.dispose();
  }
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Container(
        child: new StreamBuilder(
            initialData: 0,
            stream: _pageBloc.stream,
            builder: (context, snapShot) {
              return new Column(
                children: <Widget>[
                  new Expanded(
                      child: new Center(
                          child: new Text(snapShot.data.toString()))),
                  new Center(
                    child: new FlatButton(
                        onPressed: () {
                          _pageBloc.add();
                        },
                        color: Colors.blue,
                        child: new Text("+")),
                  ),
                  new SizedBox(
                    height: 100,
                  )
                ],
              );
            }),
      ),
    );
  }
}
class PageBloc {
  int _count = 0;
  ///StreamController
  StreamController<int> _countController = StreamController<int>();
  ///对外提供入口
  StreamSink<int> get _countSink => _countController.sink;
  ///提供 stream StreamBuilder 订阅
  Stream<int> get stream => _countController.stream;
  void dispose() {
    _countController.close();
  }
  void add() {
    _count++;
    _countSink.add(_count);
  }
}