FlutterBloc 2.1.1迁移至6.0.6
作者:互联网
依赖于Bloc Package升级(2.0.0->6.1.0)
Provider扁平化依赖通过nested实现
initialState
属性删除,主要是为了兼容懒加载(巨坑,由于之前工程在初始化需要进行缓存及逻辑计算,导致初始化函数机构混乱,再加上受限于先于flutter独特的初始化方法,没办法通过this直接引用原方法,所以针对这点还需要尽量减少initialState
的逻辑)语法糖变更,
Provider.of
的方式可以直接通过context.read/context.watch
来实现新增
BlocConsumer
,加强了对bloc流事件传递流程步骤,进一步细化,基于BlocBuilder语法糖
Bloc变更
StateSubject
&EventSubject
移除,通过StreamController
来管理Event
和State
流- 通过
BlocObserver
替代BlocDelegate
,完善了Bloc生命周期监听 - 引入
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