从前面的demo
return BlocBuilder<TestBloc, TestState>(builder: (context, state) {
print("_Test1State -----");
if(state.runtimeType ==TestSuccessState){
print((state as TestSuccessState).data);
}
return Container(height: 30,color: Colors.black, child: Text('Test1',style: Theme.of(context).textTheme.bodyLarge!.copyWith(color: Colors.white),),);
// }
}
);
我们看看BlocBuilder都做了什么事,BlocBuilder继承于BlocBuilderBase
class BlocBuilder<B extends StateStreamable<S>, S>
extends BlocBuilderBase<B, S> {
/// {@macro bloc_builder}
/// {@macro bloc_builder_build_when}
const BlocBuilder({
Key? key,
required this.builder,
B? bloc,
BlocBuilderCondition<S>? buildWhen,
}) : super(key: key, bloc: bloc, buildWhen: buildWhen);
/// The [builder] function which will be invoked on each widget build.
/// The [builder] takes the `BuildContext` and current `state` and
/// must return a widget.
/// This is analogous to the [builder] function in [StreamBuilder].
final BlocWidgetBuilder<S> builder;
@override
Widget build(BuildContext context, S state) => builder(context, state);
}
BlocBuilderBase继承于StatefulWidget
abstract class BlocBuilderBase<B extends StateStreamable<S>, S>
extends StatefulWidget {
/// {@macro bloc_builder_base}
const BlocBuilderBase({Key? key, this.bloc, this.buildWhen})
: super(key: key);
/// The [bloc] that the [BlocBuilderBase] will interact with.
/// If omitted, [BlocBuilderBase] will automatically perform a lookup using
/// [BlocProvider] and the current `BuildContext`.
final B? bloc;
/// {@macro bloc_builder_build_when}
final BlocBuilderCondition<S>? buildWhen;
/// Returns a widget based on the `BuildContext` and current [state].
Widget build(BuildContext context, S state);
@override
State<BlocBuilderBase<B, S>> createState() => _BlocBuilderBaseState<B, S>();
}
class _BlocBuilderBaseState<B extends StateStreamable<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
void didUpdateWidget(BlocBuilderBase<B, S> oldWidget) {
super.didUpdateWidget(oldWidget);
final oldBloc = oldWidget.bloc ?? context.read<B>();
final currentBloc = widget.bloc ?? oldBloc;
if (oldBloc != currentBloc) {
_bloc = currentBloc;
_state = _bloc.state;
}
}
@override
void didChangeDependencies() {
super.didChangeDependencies();
final bloc = widget.bloc ?? context.read<B>();
if (_bloc != bloc) {
_bloc = bloc;
_state = _bloc.state;
}
}
@override
Widget build(BuildContext context) {
if (widget.bloc == null) {
// Trigger a rebuild if the bloc reference has changed.
// See https://github.com/felangel/bloc/issues/2127.
context.select<B, bool>((bloc) => identical(_bloc, bloc));
}
return BlocListener<B, S>(
bloc: _bloc,
listenWhen: widget.buildWhen,
listener: (context, state) => setState(() => _state = state),
child: widget.build(context, _state),
);
}
}
我们先看看_BlocBuilderBaseState的initState方法,这里如果当前bloc为空,则调用context的read方法,我们构建BlocBuilder时并没有传bloc 所以这里是空,这里就到了ReadContext的read方法
T read<T>() {
return Provider.of<T>(this, listen: false);
}
我们调用到provider的of方法
static T of<T>(BuildContext context, {bool listen = true}) {
assert(
context.owner!.debugBuilding ||
listen == false ||
debugIsInInheritedProviderUpdate,
'''
Tried to listen to a value exposed with provider, from outside of the widget tree.
This is likely caused by an event handler (like a button's onPressed) that called
Provider.of without passing `listen: false`.
To fix, write:
Provider.of<$T>(context, listen: false);
It is unsupported because may pointlessly rebuild the widget associated to the
event handler, when the widget tree doesn't care about the value.
The context used was: $context
''',
);
final inheritedElement = _inheritedElementOf<T>(context);
if (listen) {
// bind context with the element
// We have to use this method instead of dependOnInheritedElement, because
// dependOnInheritedElement does not support relocating using GlobalKey
// if no provider were found previously.
context.dependOnInheritedWidgetOfExactType<_InheritedProviderScope<T?>>();
}
final value = inheritedElement?.value;
if (_isSoundMode) {
if (value is! T) {
throw ProviderNullException(T, context.widget.runtimeType);
}
return value;
}
return value as T;
}
这里的inheritedElement就是我们前面一篇创建的_InheritedProviderScopeElement
final value = inheritedElement?.value;
这个代码获取value
@override
T get value => _delegateState.value;
这里的_delegateState是_CreateInheritedProviderState,我们看看其获取value的方法
T get value {
if (_didInitValue && _initError != null) {
// TODO(rrousselGit) update to use Error.throwWithStacktTrace when it reaches stable
throw StateError(
'Tried to read a provider that threw during the creation of its value.\n'
'The exception occurred during the creation of type $T.\n\n'
'${_initError?.toString()}',
);
}
bool? _debugPreviousIsInInheritedProviderCreate;
bool? _debugPreviousIsInInheritedProviderUpdate;
assert(() {
_debugPreviousIsInInheritedProviderCreate =
debugIsInInheritedProviderCreate;
_debugPreviousIsInInheritedProviderUpdate =
debugIsInInheritedProviderUpdate;
return true;
}());
if (!_didInitValue) {
_didInitValue = true;
if (delegate.create != null) {
assert(debugSetInheritedLock(true));
try {
assert(() {
debugIsInInheritedProviderCreate = true;
debugIsInInheritedProviderUpdate = false;
return true;
}());
_value = delegate.create!(element!);
} catch (e, stackTrace) {
_initError = FlutterErrorDetails(
library: 'provider',
exception: e,
stack: stackTrace,
);
rethrow;
} finally {
assert(() {
debugIsInInheritedProviderCreate =
_debugPreviousIsInInheritedProviderCreate!;
debugIsInInheritedProviderUpdate =
_debugPreviousIsInInheritedProviderUpdate!;
return true;
}());
}
assert(debugSetInheritedLock(false));
assert(() {
delegate.debugCheckInvalidValueType?.call(_value as T);
return true;
}());
}
if (delegate.update != null) {
try {
assert(() {
debugIsInInheritedProviderCreate = false;
debugIsInInheritedProviderUpdate = true;
return true;
}());
_value = delegate.update!(element!, _value);
} finally {
assert(() {
debugIsInInheritedProviderCreate =
_debugPreviousIsInInheritedProviderCreate!;
debugIsInInheritedProviderUpdate =
_debugPreviousIsInInheritedProviderUpdate!;
return true;
}());
}
assert(() {
delegate.debugCheckInvalidValueType?.call(_value as T);
return true;
}());
}
}
element!._isNotifyDependentsEnabled = false;
_removeListener ??= delegate.startListening?.call(element!, _value as T);
element!._isNotifyDependentsEnabled = true;
assert(delegate.startListening == null || _removeListener != null);
return _value as T;
}
注意中间有一段代码
_value = delegate.create!(element!);
这里的delegate对应的就是_CreateInheritedProvider
调用它的create方法就是我们在BlocProvider传的create方法
@override
Widget build(BuildContext context) {
return BlocProvider(
create: (context) =>TestBloc(),
child: MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home:MyHomePage(title: 'dddd',),
));
}
这里即会进入TestBloc的初始化操作
前面的get value还有
_removeListener ??= delegate.startListening?.call(element!, _value as T);
这里会调用BlocProvider的
Bloc的初始化操作我们下一篇来讲
static VoidCallback _startListening(
InheritedContext<StateStreamable?> e,
StateStreamable value,
) {
final subscription = value.stream.listen(
(dynamic _) => e.markNeedsNotifyDependents(),
);
return subscription.cancel;
}