ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

FlutterBloc 2.1.1迁移至6.0.6

2020-10-31 04:00:48  阅读:292  来源: 互联网

标签:Widget FlutterBloc dart cubit state bloc context 6.0 2.1


  1. 依赖于Bloc Package升级(2.0.0->6.1.0)

  2. Provider扁平化依赖通过nested实现

  3. initialState属性删除,主要是为了兼容懒加载(巨坑,由于之前工程在初始化需要进行缓存及逻辑计算,导致初始化函数机构混乱,再加上受限于先于flutter独特的初始化方法,没办法通过this直接引用原方法,所以针对这点还需要尽量减少initialState的逻辑)

  4. 语法糖变更,Provider.of的方式可以直接通过context.read/context.watch来实现

  5. 新增BlocConsumer,加强了对bloc流事件传递流程步骤,进一步细化,基于BlocBuilder语法糖

Bloc变更

  1. StateSubject & EventSubject移除,通过StreamController来管理EventState
  2. 通过BlocObserver替代BlocDelegate,完善了Bloc生命周期监听
  3. 引入Cubit基类,将State大部分逻辑抽屉,Bloc作为其子类更注重Event事件的管理

Bloc类关系图

  • 6.1.0

  • 2.0.0

BlocBuilderBase

  • 相比之前的版本主要是将state的监听转移到BlocListener中执行,对职责划分进行了优化
  • 关系图
DiagnosticableTree (diagnostics.dart)
    Widget (framework.dart)
        StatefulWidget (framework.dart)
            BlocBuilderBase (bloc_builder.dart)
                BlocBuilder (bloc_builder.dart)
  • 实现
class _BlocBuilderBaseState<C extends Cubit<S>, S>
    extends State<BlocBuilderBase<C, S>> {
  C _cubit;
  S _state;

  @override
  void initState() {
    super.initState();
    /// 1.初始化默认会设置cubit(bloc)和state
    _cubit = widget.cubit ?? context.bloc<C>();
    _state = _cubit.state;
  }

  @override
  void didUpdateWidget(BlocBuilderBase<C, S> oldWidget) { ...
  ///2. cubit(bloc)更新检测,从新赋值
  }

  @override
  Widget build(BuildContext context) {
  ///3. 通过listener来监听state变更,调用`setState`更新widget
    return BlocListener<C, S>(
      cubit: _cubit,
      ///4. 通过用户自定义`listenWhen`和`build`实现页面按条件更新
      listenWhen: widget.buildWhen,
      listener: (context, state) => setState(() => _state = state),
      child: widget.build(context, _state),
    );
  }
}

BlocListenerBase

  • 继承链变更SingleChildStatefulWidget,主要是为了方便Nested对嵌套Widget进行扁平化压缩,其它无变化
  • 管理bloc的state流事件订阅和释放
  • 关系图
DiagnosticableTree (diagnostics.dart)
    Widget (framework.dart)
        StatefulWidget (framework.dart)
            SingleChildStatefulWidget (nested.dart)
                BlocListenerBase (bloc_listener.dart)
                    BlocListener (bloc_listener.dart)
  • 实现
class _BlocListenerBaseState<C extends Cubit<S>, S>
    extends SingleChildState<BlocListenerBase<C, S>> { ...
  @override
  void initState() { ...
    _subscribe();
  }

  @override
  void didUpdateWidget(BlocListenerBase<C, S> oldWidget) { ..
        _unsubscribe(); ...
      _subscribe(); ...

  @override
  void dispose() {
    _unsubscribe(); ... 

BlocConsumer

  • 扩展了State的监听流程
  • 关系
DiagnosticableTree (diagnostics.dart)
    Widget (framework.dart)
        StatelessWidget (framework.dart)
            BlocConsumer (bloc_consumer.dart)

  • 实现
class BlocConsumer<C extends Cubit<S>, S> extends StatelessWidget {
  /// 1. 初始化条件设定, 增加对listener和build的前置条件过滤
  const BlocConsumer({
    Key key,
    @required this.builder,
    @required this.listener,
    this.cubit,
    this.buildWhen,
    this.listenWhen,
  })   ...
  
  /// 2. 对blocBuilder进行默认的包装,算是一个语法糖吧
  @override
  Widget build(BuildContext context) {
    final cubit = this.cubit ?? context.bloc<C>();
    return BlocBuilder<C, S>(
      cubit: cubit,
      builder: builder,
      buildWhen: (previous, current) {
        if (listenWhen?.call(previous, current) ?? true) {
          listener(context, current);
        }
        return buildWhen?.call(previous, current) ?? true;
      },
    );
  }
}
  • 使用
/// BlocConsumer<BlocA, BlocAState>(
///   listenWhen: (previous, current) {
///     // return true/false to determine whether or not
///     // to invoke listener with state
///   },
///   listener: (context, state) {
///     // do stuff here based on BlocA's state
///   },
///   buildWhen: (previous, current) {
///     // return true/false to determine whether or not
///     // to rebuild the widget with state
///   },
///   builder: (context, state) {
///     // return widget here based on BlocA's state
///   }
/// )

BlocProvider

  • 继承链变更
DiagnosticableTree (diagnostics.dart)
    Widget (framework.dart)
        StatelessWidget (framework.dart)
            SingleChildStatelessWidget (nested.dart)
                BlocProvider (bloc_provider.dart)
  • 实现-初始化
///1. 通过Value创建,销毁时不会自动释放
  BlocProvider.value({
    Key key,
    @required T value,
    Widget child,
  }) : this._(
          key: key,
          create: (_) => value,
          child: child,
        );
///2. 通过create方式创建,销毁时会释放bloc
  @override
  Widget buildWithChild(BuildContext context, Widget child) {
    return InheritedProvider<T>(
      create: _create,
      dispose: _dispose,
      child: child,
      lazy: lazy,
    );
  }
  • 构建用户界面配置信息
  @override
  Widget buildWithChild(BuildContext context, Widget child) {
    return InheritedProvider<T>(
      create: _create,   //提供传入的value(cubit/bloc)
      dispose: _dispose, //可选,通过value初始化时则为null
      child: child,      //用户定义的child包装
      lazy: lazy,        //决定create是否懒加载,及用到时初始化
    );
  }

MultiProvider

  • 扁平化多个Provider,基于Nested实现
DiagnosticableTree (diagnostics.dart)
    Widget (framework.dart)
        StatelessWidget (framework.dart)
            Nested (nested.dart)
                MultiProvider (provider.dart)
                    MultiBlocListener (multi_bloc_listener.dart)
                    MultiBlocProvider (multi_bloc_provider.dart)
                    MultiRepositoryProvider (multi_repository_provider.dart)

Provider

DiagnosticableTree (diagnostics.dart)
    Widget (framework.dart)
        StatelessWidget (framework.dart)
            SingleChildStatelessWidget (nested.dart)
                InheritedProvider (provider.dart)
                    Provider (provider.dart)
                        RepositoryProvider (repository_provider.dart)

小结

  • Flutter Bloc升级整体风险可空,initialState修改工作量大,代码结构上会有一些冲突,可采用静态方法替换实例先适配initialState.
  • Provider基于Nested进行了重新包装,它原来所依赖的ValueDelegate系列的类被移除,目前仅Navigator有采用次类进行包裹,PageNavigator的语法糖失效,需要进行适配,可先临时通过globalKey访问。

TODO:

  • Provider,Nested与PageNavigator适配

标签:Widget,FlutterBloc,dart,cubit,state,bloc,context,6.0,2.1
来源: https://www.cnblogs.com/wwoo/p/flutterbloc-211qian-yi-zhi606.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有