Flutter UI与数据分离(streamBuilder)

1.简书

页面中UI与数据分离有多种方案,现在使用的一种就是StreamBuilder;

2.页面结构

第一步:将bloc与widget绑定

class Home extends StatelessWidget {
  @override 
  Widget build(BuildContext context){
    return BlocProvider(
          bloc:HomeBloc(),
          child:HomeWidget()
    )
  }
}

第二部:在Widget中获取bloc实例

class HomeWidget extends StatefulWidget {
  HomeBloc _homeBloc;
  @override 
  void initState(){
    _homeBloc = BlocProvider.of<HomeBloc>(context);
  }
  @override 
  Widget build(BuildContext context){
      return Column(children:<Widget>[
        StreamBuilder(
            stream:_homeBloc.actionStream,
            initialData:0,
            builder:(BuilderContext context,AsyncSnapshot snapshot){
                  return Text(shapshot.data);
              }

      ),
      RaisedButton(child: Text('+'),onPressed: () => _homeBloc.increment(),)

    ])
  
  }

}

第三步:创建homeBloc(此处实现了一个抽象类,是因为BlocProvider里面规定了所有的Bloc必须继承BlocBase)

class HomeBloc implements BlocBase {
    int _counter = 0;
    StreamController<int> _streamController = StreamController<int> ();//初始化一个Stream控制器
    StreamSink get actionSink => _streamController.sink;//可以调用StreamController中的方法
    StreamSink get actionStream => _streamController.stream;//Stream里面的数据流向
    
    /**
     * 增加数据的方法
     */
    increment(){
       _counter++;
      actionSink.add(_counter);
  }
}

3.BlocProvider实现

import 'package:flutter/widgets.dart';

abstract class BlocBase {
  void dispose();
}

class BlocProvider<T extends BlocBase> extends StatefulWidget{
  BlocProvider({
    Key key,
    @required this.bloc,
    @required this.child

  }):super(key:key);

  final T bloc;
  final Widget child;
  static T of<T extends BlocBase>(BuildContext context){
    final type = _typeOf<BlocProvider<T>>();
    BlocProvider<T> provider = context.ancestorWidgetOfExactType(type);
    return provider.bloc;
  }

  ///获取类型
  static Type _typeOf<T>() => T;


  @override
  State<StatefulWidget> createState() => _BlocProvider();
}

class _BlocProvider extends State<BlocProvider<BlocBase>>{
  @override
  void dispose() {
    // TODO: implement dispose
    super.dispose();
    widget.bloc.dispose();//自动销毁
  }

  @override
  Widget build(BuildContext context) {
    return widget.child;
  }
}