Bloc
大致流程

image.png
源碼解讀
BlocProvider
1、繼承SingleChildStatelessWidget,就是一個(gè)widget,通過(guò)create 傳入一個(gè)Bloc對(duì)象
class BlocProvider<T extends BlocBase<Object?>>
extends SingleChildStatelessWidget with BlocProviderSingleChildWidget
Bloc
1、Bloc繼承自BlocBase,BlocBase中創(chuàng)建了StreamController對(duì)象,為多訂閱對(duì)象
其中on<CounterEvent>((event, emit)為初始化創(chuàng)建_eventController監(jiān)聽(tīng)
class CounterBloc extends Bloc<CounterEvent, CounterState> {
CounterBloc() : super(const CounterInitial(0)) {
///建立_eventController通知監(jiān)聽(tīng)
on<CounterEvent>((event, emit) {
if (event is CounterEventTest) {
emit.call(CounterInitial(event.count));
}
});
}
}
2、Bloc中創(chuàng)建_eventController,為事件通知
abstract class Bloc<Event, State> extends BlocBase<State> {
...
final _eventController = StreamController<Event>.broadcast();
3、BlocBase創(chuàng)建_stateController,為狀態(tài)刷新通知
abstract class BlocBase<State> {
StreamController<State>? __stateController;
StreamController<State> get _stateController {
return __stateController ??= StreamController<State>.broadcast();
}
4、add方法是執(zhí)行廣播通知
void add(Event event) {
if (_eventController.isClosed) return;
try {
onEvent(event);
/// 廣播通知
_eventController.add(event);
} catch (error, stackTrace) {
onError(error, stackTrace);
}
}
///void on<E extends Event>中的監(jiān)聽(tīng)回調(diào)
_eventController.stream.where((event) => event is E).cast<E>(),
(dynamic event) {
void onEmit(State state) {
if (isClosed) return;
if (this.state == state && _emitted) return;
onTransition(Transition(
currentState: this.state,
event: event as E,
nextState: state,
));
emit(state)
5、處理完數(shù)據(jù)之后執(zhí)行emit()方法,其中emit方法是stateController廣播
void emit(State state) {
if (_stateController.isClosed) return;
if (state == _state && _emitted) return;
onChange(Change<State>(currentState: this.state, nextState: state));
_state = state;
_stateController.add(_state);
_emitted = true;
}
BlocBuilder
1、 BlocBuilder繼承自BlocBuilderBase,_BlocBuilderBaseState中build方法返回的是BlocListener
return BlocListener<B, S>(
bloc: _bloc,
listenWhen: widget.buildWhen,
///傳入子視圖監(jiān)聽(tīng)刷新界面方法
listener: (context, state) => setState(() => _state = state),
child: widget.build(context, _state),
);
2、BlocListener繼承BlocListenerBase,_BlocListenerBaseState中_subscribe()添加監(jiān)聽(tīng)stateController廣播通知
void _subscribe() {
_subscription = _bloc.stream.listen((state) {
if (widget.listenWhen?.call(_previousState, state) ?? true) {
///執(zhí)行父組件的listener,執(zhí)行setState刷新父組件
widget.listener(context, state);
}
_previousState = state;
});
}