1. InheritedWidget
abstract class InheritedWidget extends ProxyWidget { const InheritedWidget({ Key? key, required Widget child }) : super(key: key, child: child); @override InheritedElement createElement() => InheritedElement(this); @protected bool updateShouldNotify(covariant InheritedWidget oldWidget); }
2. StatefulWidget
abstract class StatefulWidget extends Widget { const StatefulWidget({ Key? key }) : super(key: key); @override StatefulElement createElement() => StatefulElement(this); @protected @factory State createState(); // -> Widget build(BuildContext context); }
3. StatelessWidget
abstract class StatelessWidget extends Widget { const StatelessWidget({ Key? key }) : super(key: key); @override StatelessElement createElement() => StatelessElement(this); @protected Widget build(BuildContext context); }
4.State
4.1 setState ->_element!.markNeedsBuild()
4.2 build-> Widget build(BuildContext context);
5.问题
5.1 为什么调用setState就会调用build?
因为调用markNeedsBuild方法标记element污染,需要在下一帧重建
5.2 到底是谁直接调用了build
?
5.3怎么判断是否需要更新Element
通过widget->canUpdate widget的类型和key
6.常用的类
abstract class InheritedContext<T> extends BuildContext { void markNeedsNotifyDependents(); } abstract class Element extends DiagnosticableTree implements BuildContext { void didChangeDependencies(); @protected void performRebuild(); } abstract class ComponentElement extends Element { Widget build(); } abstract class ProxyElement extends ComponentElement { //关键 方法 @protected void notifyClients(covariant ProxyWidget oldWidget); } class InheritedElement extends ProxyElement{} class _InheritedProviderScopeElement<T> extends InheritedElement implements InheritedContext<T> {} class ChangeNotifierProvider<T extends ChangeNotifier?> extends ListenableProvider<T> {} class ListenableProvider<T extends Listenable?> extends InheritedProvider<T>{} class InheritedProvider<T> extends SingleChildStatelessWidget { @override Widget buildWithChild(BuildContext context, Widget? child); //构造方法中会实例该对象 final _Delegate<T> _delegate; } class _InheritedProviderScope<T> extends InheritedWidget { @override _InheritedProviderScopeElement<T> createElement() } abstract class InheritedWidget extends ProxyWidget {} class _CreateInheritedProviderState<T> extends _DelegateState<T, _CreateInheritedProvider<T>>{ /// 关键 T? _value; T get value {} } class _CreateInheritedProvider<T> extends _Delegate<T> { ///delegate.create!(element!) final Create<T>? create; } abstract class _DelegateState<T, D extends _Delegate<T>> { _InheritedProviderScopeElement<T>? element; } class ChangeNotifier implements Listenable{ notifyListeners() }
6.1 继承关系
Widget
ProxyWidget
InheritedWidget
_InheritedProviderScope
StatelessWidget
SingleChildStatelessWidget
InheritedProvider
BuildContext
InheritedContext
Element
ComponentElement
ProxyElement
InheritedElement
_InheritedProviderScopeElement
_Delegate
_DelegateState
6.2 InheritedProvider
属性:(InheritedContext element, T value)-> StartListening
终于联系起来了value 就是ChangeNotifier 监听添加的就是markNeedsNotifyDependents方法,
notifyListeners->listener其实调用你的是markNeedsNotifyDependents
1.notifyListeners->listener->markNeedsNotifyDependents->markNeedsBuild-performRebuild->build->
notifyClients->notifyDependent->didChangeDependencies->markNeedsBuild
///该方法是在get value的时候调用的 ///ListenableProvider static VoidCallback _startListening( InheritedContext e, Listenable? value, ) { value?.addListener(e.markNeedsNotifyDependents); return () => value?.removeListener(e.markNeedsNotifyDependents); } ///_CreateInheritedProviderState @override T get value { if (_didInitValue && _value is! T) { 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.', ); } if (!_didInitValue) { _didInitValue = true; if (delegate.create != null) { try { _value = delegate.create!(element!); } finally { } } if (delegate.update != null) { try { _value = delegate.update!(element!, _value); } finally { } } } element!._isNotifyDependentsEnabled = false; _removeListener ??= delegate.startListening?.call(element!, _value as T); element!._isNotifyDependentsEnabled = true; return _value as T; } ///_InheritedProviderScopeElement /// @override void performRebuild() { if (_firstBuild) { _firstBuild = false; _delegateState = widget.owner._delegate.createState()..element = this; } super.performRebuild(); } ///InheritedElement @override void notifyClients(InheritedWidget oldWidget) { for (final Element dependent in _dependents.keys) { notifyDependent(oldWidget, dependent); } } } ///Element @mustCallSuper void didChangeDependencies() { markNeedsBuild(); } ///ComponentElement @override void performRebuild() { Widget? built; try { built = build(); } catch (e, stack) { built = ErrorWidget.builder(), } finally { _dirty = false; } try { _child = updateChild(_child, built, slot); } catch (e, stack) { built = ErrorWidget.builder(); _child = updateChild(null, built, slot); } } ///_InheritedProviderScopeElement @override void markNeedsNotifyDependents() { if (!_isNotifyDependentsEnabled) { return; } markNeedsBuild(); _shouldNotifyDependents = true; } ///_InheritedProviderScopeElement @override Widget build() { if (widget.owner._lazy == false) { value; // this will force the value to be computed. } _delegateState.build( isBuildFromExternalSources: _isBuildFromExternalSources, ); _isBuildFromExternalSources = false; if (_shouldNotifyDependents) { _shouldNotifyDependents = false; notifyClients(widget); } return super.build(); } ///InheritedProviderScopeElement @override void notifyDependent(InheritedWidget oldWidget, Element dependent) { final dependencies = getDependencies(dependent); if (kDebugMode) { ProviderBinding.debugInstance.providerDidChange(_debugId); } var shouldNotify = false; if (dependencies != null) { if (dependencies is _Dependency<T>) { if (dependent.dirty) { return; } for (final updateShouldNotify in dependencies.selectors) { try { shouldNotify = updateShouldNotify(value); } finally { } if (shouldNotify) { break; } } } else { shouldNotify = true; } } if (shouldNotify) { dependent.didChangeDependencies(); } } ///InheritedProvider @override Widget buildWithChild(BuildContext context, Widget? child) { return _InheritedProviderScope<T>( owner: this, child: builder != null ? Builder( builder: (context) => builder!(context, child), ) : child!, ); } } ///_InheritedProviderScope @override _InheritedProviderScopeElement<T> createElement() { return _InheritedProviderScopeElement<T>(this); } ///_CreateInheritedProvider @override _CreateInheritedProviderState<T> createState() =>_CreateInheritedProviderState();
6.3 Provider.of
注册监听并获取ChangeNotifier
BuildContext->dependOnInheritedElement->InheritedElement->updateDependencies->setDependencies->添加到_dependents(需要监听的Map)中
///Provider static T of<T>(BuildContext context, {bool listen = true}) { final inheritedElement = _inheritedElementOf<T>(context); if (listen) { context.dependOnInheritedElement(inheritedElement); } return inheritedElement.value; } static _InheritedProviderScopeElement<T> _inheritedElementOf<T>( BuildContext context, ) { ///context.getElementForInheritedWidgetOfExactType() } ///Element @override InheritedElement? getElementForInheritedWidgetOfExactType<T extends InheritedWidget>() { assert(_debugCheckStateIsActiveForAncestorLookup()); final InheritedElement? ancestor = _inheritedWidgets == null ? null : _inheritedWidgets![T]; return ancestor; } ///一级一级的赋值给子节点Element的 _inheritedWidgets 变量 /// mount和activate中调用_updateInheritance方法 @override void _updateInheritance() { final Map<Type, InheritedElement>? incomingWidgets = _parent?._inheritedWidgets; if (incomingWidgets != null) _inheritedWidgets = HashMap<Type, InheritedElement>.from(incomingWidgets); else _inheritedWidgets = HashMap<Type, InheritedElement>(); _inheritedWidgets![widget.runtimeType] = this; } /// ///notifyClients中遍历 final Map<Element, Object?> _dependents /// Set<InheritedElement>? _dependencies; ///BuildContext @override InheritedWidget dependOnInheritedElement(InheritedElement ancestor, { Object? aspect }) { assert(ancestor != null); _dependencies ??= HashSet<InheritedElement>(); _dependencies!.add(ancestor); ancestor.updateDependencies(this, aspect); return ancestor.widget; }
7.Selector Consumer Builder
class Builder extends StatelessWidget { final WidgetBuilder builder; @override Widget build(BuildContext context) => builder(context); } class Consumer<T> extends SingleChildStatelessWidget { @override Widget buildWithChild(BuildContext context, Widget? child) { return builder( context, Provider.of<T>(context), child, ); } } class Selector0<T> extends SingleChildStatefulWidget { @override _Selector0State<T> createState() => _Selector0State<T>(); } class _Selector0State<T> extends SingleChildState<Selector0<T>> { @override Widget buildWithChild(BuildContext context, Widget? child) { if (shouldInvalidateCache) { value = selected; oldWidget = widget; cache = widget.builder( context, selected, child, ); } return cache!; } } class Selector<A, S> extends Selector0<S> { Selector({ Key? key, required ValueWidgetBuilder<S> builder, required S Function(BuildContext, A) selector, ShouldRebuild<S>? shouldRebuild, Widget? child, }) : super( key: key, shouldRebuild: shouldRebuild, builder: builder, selector: (context) => selector(context, Provider.of(context)), child: child, ); }
参考资料
- flutter源码
- Flutter Provider的另一面