源码篇:Flutter Bloc背后的思想,一篇纠结的文章 (4)

将上面的代码精简下

abstract class BlocBase<T> { BlocBase(this.state) : _stateController = StreamController<T>.broadcast(); final StreamController<T> _stateController; T state; bool _emitted = false; Stream<T> get stream => _stateController.stream; void emit(T newState) { if (_stateController.isClosed) return; if (state == newState && _emitted) return; state = newState; _stateController.add(state); _emitted = true; } @mustCallSuper Future<void> close() async { await _stateController.close(); } } BlocBuilder

BlocBuilder对StreamBuilder的用法做了很多精简,来看下内部实现

BlocBuilder

此处需要关注下builder参数; buildWhen是个判断是否需要更新的参数

build方法里面调用了builder,需要看下父类BlocBuilderBase

typedef BlocWidgetBuilder<S> = Widget Function(BuildContext context, S state); class BlocBuilder<B extends BlocBase<S>, S> extends BlocBuilderBase<B, S> { const BlocBuilder({ Key? key, required this.builder, B? bloc, BlocBuilderCondition<S>? buildWhen, }) : super(key: key, bloc: bloc, buildWhen: buildWhen); final BlocWidgetBuilder<S> builder; @override Widget build(BuildContext context, S state) => builder(context, state); }

BlocBuilderBase

context.read< B>() 和 Provider.of(this, listen: false)效果是一样的,就是对后者的一个封装

此处通过context.read< B>() 拿到了 我们在 BlocProvider中传入的XxxBloc对象,赋值给了_BlocBuilderBaseState中的 _bloc变量

BlocBuilderBase抽象了一个build方法,在 _BlocBuilderBaseState中赋值给了 BlocListener

BlocBuilderBase还没法看出刷新逻辑,几个重要的参数:_bloc,listener,widget.build都传给了BlocListener;需要看下BlocListener的实现

abstract class BlocBuilderBase<B extends BlocBase<S>, S> extends StatefulWidget { const BlocBuilderBase({Key? key, this.bloc, this.buildWhen}) : super(key: key); final B? bloc; final BlocBuilderCondition<S>? buildWhen; Widget build(BuildContext context, S state); @override State<BlocBuilderBase<B, S>> createState() => _BlocBuilderBaseState<B, S>(); } class _BlocBuilderBaseState<B extends BlocBase<S>, S> extends State<BlocBuilderBase<B, S>> { late B _bloc; late S _state; @override void initState() { super.initState(); _bloc = widget.bloc ?? context.read<B>(); _state = _bloc.state; } ... @override Widget build(BuildContext context) { ... return BlocListener<B, S>( bloc: _bloc, listenWhen: widget.buildWhen, listener: (context, state) => setState(() => _state = state), child: widget.build(context, _state), ); } }

BlocListener:参数传给父类的构造函数了,需要看下父类BlocListenerBase的实现

class BlocListener<B extends BlocBase<S>, S> extends BlocListenerBase<B, S> const BlocListener({ Key? key, required BlocWidgetListener<S> listener, B? bloc, BlocListenerCondition<S>? listenWhen, Widget? child, }) : super( key: key, child: child, listener: listener, bloc: bloc, listenWhen: listenWhen, ); }

BlocListenerBase:精简了一些逻辑代码

abstract class BlocListenerBase<B extends BlocBase<S>, S> extends SingleChildStatefulWidget { const BlocListenerBase({ Key? key, required this.listener, this.bloc, this.child, this.listenWhen, }) : super(key: key, child: child); final Widget? child; final B? bloc; final BlocWidgetListener<S> listener; final BlocListenerCondition<S>? listenWhen; @override SingleChildState<BlocListenerBase<B, S>> createState() => _BlocListenerBaseState<B, S>(); } class _BlocListenerBaseState<B extends BlocBase<S>, S> extends SingleChildState<BlocListenerBase<B, S>> { StreamSubscription<S>? _subscription; late B _bloc; late S _previousState; @override void initState() { super.initState(); _bloc = widget.bloc ?? context.read<B>(); _previousState = _bloc.state; _subscribe(); } ... @override Widget buildWithChild(BuildContext context, Widget? child) { return child!; } @override void dispose() { _unsubscribe(); super.dispose(); } void _subscribe() { _subscription = _bloc.stream.listen((state) { if (widget.listenWhen?.call(_previousState, state) ?? true) { widget.listener(context, state); } _previousState = state; }); } void _unsubscribe() { _subscription?.cancel(); _subscription = null; } }

终于找了关键的代码了!

可以发现Bloc是通过 StreamController 和 listen配合实现刷新的

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zwsxyx.html