首页 > 建站教程 > dart >  dart笔记21:BlocProvider工具实现管理多个stream流正文

dart笔记21:BlocProvider工具实现管理多个stream流

dart笔记21:BlocProvider工具实现管理多个stream流,此笔记代码是基于“基于Bloc stream流实现数据处理和UI渲染分离”代码的基础上进行的修改,通过实现BlocProvider类,来管理多个stream流,更加强大。

bloc_base.dart代码:
abstract class BlocBase {
  void dispose();
}
bloc_provider.dart代码:
import 'package:flutter/widgets.dart';
import 'bloc_base.dart';

Type _typeOf<T>() => T;

class BlocProvider<T extends BlocBase> extends StatefulWidget {
  BlocProvider({Key key, @required Widget this.child, @required this.blocs})
      : super(key: key);

  final Widget child;
  final List<T> blocs;

  _BlocProviderState<T> createState() => _BlocProviderState<T>();

  static List<T> of<T extends BlocBase>(BuildContext context) {
    final type = _typeOf<_BlocProviderInherited<T>>();
    //通过BuildContext可以跨组件获取对象
    //ancestorInheritedElementForWidgetOfExactType方法获得指定类型的InheritedWidget进而获取它的共享数据
    _BlocProviderInherited<T> provider =
        // ignore: deprecated_member_use
        context.ancestorInheritedElementForWidgetOfExactType(type)?.widget;
    return provider?.blocs;
  }
}

class _BlocProviderState<T extends BlocBase> extends State<BlocProvider<T>> {
  @override
  void dispose() {
    widget.blocs.map((bloc) {
      bloc.dispose();
    });
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return _BlocProviderInherited<T>(
      blocs: widget.blocs,
      child: widget.child,
    );
  }
}

/**
 * InheritedWidget是flutter的一个功能型的Widget基类
 * 它能有效的将数据再当前Widget树中向它的子Widget树传递
 */
class _BlocProviderInherited<T> extends InheritedWidget {
  _BlocProviderInherited(
      {Key key, @required Widget child, @required this.blocs})
      : super(key: key, child: child);

  final List<T> blocs;

  /**
   * 用来告诉InheritedWidget如果对数据进行了修改,
   * 是否必须将通知传递给所有的子Widget(已注册/已订阅)
   */
  @override
  bool updateShouldNotify(InheritedWidget oldWidget) => false;
}
bloc_counter.dart代码:
import 'dart:async';
import 'bloc_base.dart';

class BlocCounter extends BlocBase {
  final _controller = StreamController<int>();

  get _counter => _controller.sink;

  get counter => _controller.stream;

  void increment(int count) {
    _counter.add(++count);
  }

  @override
  void dispose() {
    _controller.close();
  }
}
main.dart代码:
import 'package:flutter/material.dart';
import 'bloc_counter.dart';
import 'bloc_provider.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'blocprovider示例',
      home: BlocProvider(
        //放在顶层组件,下面的子组件才能传递数据,管理子组件的所有bloc
        child: MyHomePage(),
        blocs: [BlocCounter()], //一系列的blocs,管理这一系列的bloc
      ),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key}) : super(key: key);

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  int _counter = 0;

  _MyHomePageState();

  void _incrementCounter() {
    // 调用第一个bloc的increment方法
    BlocProvider.of<BlocCounter>(context).first.increment(_counter);
  }

  @override
  void initState() {
    // 监听第一个bloc的counter的变化
    BlocProvider.of<BlocCounter>(context).first.counter.listen((_count) {
      setState(() {
        _counter = _count;
      });
    });
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('blocprovider示例'),
      ),
      body: Center(
        child: Text(
          '$_counter',
          // ignore: deprecated_member_use
          style: Theme.of(context).textTheme.display1,
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: _incrementCounter,
        child: Icon(Icons.add),
      ),
    );
  }

  @override
  void dispose() {
    super.dispose();
  }
}