和InheritedWidget 类似的,我们来分析 Provider , 还是设计到
收集和通知两个过程
1. 收集过程
void main() {
runApp(
// 可以使用多个 Provider
MultiProvider(
providers: [
// ChangeNotifierProvider 其实就是 ChangeNotifier 容器,使用组合方式来接入 ChangeNotifier
ChangeNotifierProvider(create: (_) {
return HYCounterViewModel();
}),
],
child: const MyApp(),
));
}
class HYCounterViewModel extends ChangeNotifier {
int _counter = 0;
HYCounterViewModel();
int get counter => _counter;
set counter(int value) {
_counter = value;
notifyListeners();
}
@override
void addListener(VoidCallback listener) {
// TODO: implement addListener
super.addListener(listener);
}
}
class ProviceShareState extends StatefulWidget {
const ProviceShareState({super.key});
@override
State<ProviceShareState> createState() => _ProviceShareStateState();
}
class _ProviceShareStateState extends State<ProviceShareState> {
int _count = 0;
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Provider test"),
),
body: Column(
children: [
HYShowData01(),
HYShowData02(),
Consumer<HYCounterViewModel>(builder: (context, counterVM, widget) {
return FloatingActionButton(
child: Icon(Icons.pets),
onPressed: () {
counterVM.counter += 1;
});
})
],
),
);
}
}
class HYShowData01 extends StatelessWidget {
const HYShowData01({super.key});
@override
Widget build(BuildContext context) {
print("HYShowData01 --- build");
return Card(
color: Colors.red,
child: Text("当前计数1: ${Provider.of<HYCounterViewModel>(context).counter}"),
);
}
}
class HYShowData02 extends StatefulWidget {
const HYShowData02({super.key});
@override
State<HYShowData02> createState() => _HYShowData02State();
}
class _HYShowData02State extends State<HYShowData02> {
@override
Widget build(BuildContext context) {
print("HYShowData02 --- build");
return Card(
color: Colors.blue,
child: MYConsumer<HYCounterViewModel>(
builder: (context, value, child) {
return Text("当前计数2: ${value.counter}");
},
),
);
}
@override
void didChangeDependencies() {
super.didChangeDependencies();
print("didChangeDependencies: _HYShowData02State");
}
@override
void didUpdateWidget(covariant HYShowData02 oldWidget) {
super.didUpdateWidget(oldWidget);
print("didUpdateWidget: _HYShowData02State");
}
}
class MYConsumer<T> extends Consumer<T> {
// MYConsumer({Key? key, required Widget Function(BuildContext, dynamic, Widget?) builder})
MYConsumer({super.key, required super.builder});
@override
Widget build(BuildContext context) {
return super.build(context);
}
}
上面有两个地方设计到收集
// 收集1
Text("当前计数1: ${Provider.of<HYCounterViewModel>(context).counter}")
//收集2
MYConsumer<HYCounterViewModel>(
builder: (context, value, child) {
return Text("当前计数2: ${value.counter}");
},
)
下面我主要看看这里到底收集那些
1.1 我们先看第一种 Provider.of<HYCounterViewModel>(context).counter ,这里的context 是 HYShowData01Element
static T of<T>(BuildContext context, {bool listen = true}) {
//T: HYCounterViewModel, _InheritedProviderScope<HYCounterViewModel?>
// InheritedElement? ancestor = _inheritedWidgets![ _InheritedProviderScope<HYCounterViewModel?> ]; , 没有添加depend
final inheritedElement = _inheritedElementOf<T>(context);
if (listen) {
// 这里添加绑定, 这个和 InheritedWidget是一样的,主要是让 ancestor 用set 存储这些 context
// 方便后面的noti
context.dependOnInheritedWidgetOfExactType<_InheritedProviderScope<T?>>();
}
// value: HYCounterViewModel的对象
final value = inheritedElement?.value;
// 返回 HYCounterViewModel的对象
return value as T;
}
// 这个方法其实就是为了 组成 _InheritedProviderScope<HYCounterViewModel?> 一个类型
// 然后去 子Element._inheritedWidgets 去找当前的 _InheritedProviderScope<HYCounterViewModel?> Element
static _InheritedProviderScopeElement<T?>? _inheritedElementOf<T>(BuildContext context) {
final inheritedElement = context.getElementForInheritedWidgetOfExactType<
_InheritedProviderScope<T?>>() as _InheritedProviderScopeElement<T?>?;
return inheritedElement;
}
// Element
@override
InheritedElement? getElementForInheritedWidgetOfExactType<T extends InheritedWidget>() {
final InheritedElement? ancestor = _inheritedWidgets == null ? null : _inheritedWidgets![T];
return ancestor;
}
1.2 我们看第二种, 其实和第一种方式是一样的 Provider.of<T>(context),
MYConsumer<HYCounterViewModel>(
builder: (context, value, child) {
return Text("当前计数2: ${value.counter}");
},
)
//Consumer 里面会有个build
Widget buildWithChild(BuildContext context, Widget? child) {
return builder(
context,
// 很明显这里和第一种方式是一样的,只是做了一层封装而已
Provider.of<T>(context),
child,
);
}
2. 通知过程
//HYCounterViewModel => 主动调用notifyListeners();
// ChnageNotifier
void notifyListeners() {
for (int i = 0; i < end; i++) {
// 这个listeners[0] : 存储了一个函数地址 _InheritedProviderScopeElement 里面的 void markNeedsNotifyDependents()
// 这里就完成了通知过程
_listeners[i]?.call();
}
}
接下来我们看看 _listeners 是怎么设置的
// ChangeNotifier 类中 ,因为这里调用次数太多,我们在 HYCounterViewModel中 重写 这个方法
@override
void addListener(VoidCallback listener) {
assert(ChangeNotifier.debugAssertNotDisposed(this));
if (kFlutterMemoryAllocationsEnabled && !_creationDispatched) {
MemoryAllocations.instance.dispatchObjectCreated(
library: _flutterFoundationLibrary,
className: '$ChangeNotifier',
object: this,
);
_creationDispatched = true;
}
if (_count == _listeners.length) {
if (_count == 0) {
_listeners = List<VoidCallback?>.filled(1, null);
} else {
final List<VoidCallback?> newListeners =
List<VoidCallback?>.filled(_listeners.length * 2, null);
for (int i = 0; i < _count; i++) {
newListeners[i] = _listeners[i];
}
_listeners = newListeners;
}
}
_listeners[_count++] = listener;
}
// HYCounterViewModel, 在这里打个断点
@override
void addListener(VoidCallback listener) {
// TODO: implement addListener
super.addListener(listener);
}
我们再次进入收集过程
Provider.of<HYCounterViewModel>(context) =>
再次回到前面方法
static T of<T>(BuildContext context, {bool listen = true}) {
final inheritedElement = _inheritedElementOf<T>(context);
if (listen) {
context.dependOnInheritedWidgetOfExactType<_InheritedProviderScope<T?>>();
}
// 这里会触发 下面的_InheritedProviderScopeElement get方法
final value = inheritedElement?.value;
return value as T;
}
// _InheritedProviderScopeElement
// [1 delegate]. 这个 _delegateState: _CreateInheritedProviderState
@override
T get value => _delegateState.value;
// 进入 _CreateInheritedProviderState
@override
T get value {
//[2 delegate]. 是一个 get方法 _DelegateState 类里面:
// D get delegate => element!.widget.owner._delegate as D
// 2.1 element: _InheritedProviderScopeElement (_InheritedProviderScope<HYCounterViewModel?>)
// 2.2 widget: _InheritedProviderScope (_InheritedProviderScope<HYCounterViewModel?>)
// 2.3 owner: ChangeNotifierProvider (ChangeNotifierProvider<HYCounterViewModel>)
// 2.4 _delegate : _CreateInheritedProvider (Instance of '_CreateInheritedProvider<HYCounterViewModel>')
_removeListener ??= delegate.startListening?.call(element!, _value as T);
// HYCounterViewModel对象
return _value as T;
}
// delegate.startListening?.call(element!, _value as T) =>
// ListenableProvider
static VoidCallback _startListening(
InheritedContext<Listenable?> e,
Listenable? value,
) {
// value: HYCounterViewModel对象
// 这里传递的是 e.markNeedsNotifyDependents 是_InheritedProviderScopeElement 里面的函数 markNeedsNotifyDependents ,这个函数就是标记重新更新用的
value?.addListener(e.markNeedsNotifyDependents);
return () => value?.removeListener(e.markNeedsNotifyDependents);
}
3.再看 RunApp 里面传入的 MultiProvider
runApp(
// 可以使用多个 Provider
MultiProvider(
providers: [
ChangeNotifierProvider(create: (_) {
return HYCounterViewModel();
}),
],
child: const MyApp(),
));
我们先看看 ChangeNotifierProvider
ChangeNotifierProvider(create: (_) {
return HYCounterViewModel();
})
通过继承关系我们可以看到下面的
ChangeNotifierProvider extends ListenableProvider extends InheritedProvider extends SingleChildStatelessWidget extends StatelessWidget implements SingleChildWidget
ChangeNotifierProvider 中有个 create参数,我们跟进去
/*
1. InheritedProvider._delegate = _CreateInheritedProvider(create)
2. 我们找到了 _CreateInheritedProvider
*/
InheritedProvider({
Key? key,
// 这里找到了create参数
Create<T>? create,
T Function(BuildContext context, T? value)? update,
UpdateShouldNotify<T>? updateShouldNotify,
void Function(T value)? debugCheckInvalidValueType,
StartListening<T>? startListening,
Dispose<T>? dispose,
this.builder,
bool? lazy,
Widget? child,
}) : _lazy = lazy,
// 拿到了create 去给 _CreateInheritedProvider
_delegate = _CreateInheritedProvider(
create: create,
update: update,
updateShouldNotify: updateShouldNotify,
debugCheckInvalidValueType: debugCheckInvalidValueType,
startListening: startListening,
dispose: dispose,
),
super(key: key, child: child);
进入 _CreateInheritedProvider
class _CreateInheritedProvider<T> extends _Delegate<T> {
_CreateInheritedProvider({
this.create,
this.update,
UpdateShouldNotify<T>? updateShouldNotify,
this.debugCheckInvalidValueType,
this.startListening,
this.dispose,
}) : assert(create != null || update != null),
_updateShouldNotify = updateShouldNotify;
final Create<T>? create;
final T Function(BuildContext context, T? value)? update;
final UpdateShouldNotify<T>? _updateShouldNotify;
final void Function(T value)? debugCheckInvalidValueType;
final StartListening<T>? startListening;
final Dispose<T>? dispose;
@override
// 通过_CreateInheritedProvider 创建 _CreateInheritedProviderState
// _CreateInheritedProviderState 这个state 就是前面分析调用get方法来收集用的
_CreateInheritedProviderState<T> createState() =>
_CreateInheritedProviderState();
}