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();
}
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> {
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
static VoidCallback _startListening(
InheritedContext e,
Listenable? value,
) {
value?.addListener(e.markNeedsNotifyDependents);
return () => value?.removeListener(e.markNeedsNotifyDependents);
}
@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;
}
@override
void performRebuild() {
if (_firstBuild) {
_firstBuild = false;
_delegateState = widget.owner._delegate.createState()..element = this;
}
super.performRebuild();
}
@override
void notifyClients(InheritedWidget oldWidget) {
for (final Element dependent in _dependents.keys) {
notifyDependent(oldWidget, dependent);
}
}
}
@mustCallSuper
void didChangeDependencies() {
markNeedsBuild();
}
@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);
}
}
@override
void markNeedsNotifyDependents() {
if (!_isNotifyDependentsEnabled) {
return;
}
markNeedsBuild();
_shouldNotifyDependents = true;
}
@override
Widget build() {
if (widget.owner._lazy == false) {
value;
}
_delegateState.build(
isBuildFromExternalSources: _isBuildFromExternalSources,
);
_isBuildFromExternalSources = false;
if (_shouldNotifyDependents) {
_shouldNotifyDependents = false;
notifyClients(widget);
}
return super.build();
}
@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();
}
}
@override
Widget buildWithChild(BuildContext context, Widget? child) {
return _InheritedProviderScope<T>(
owner: this,
child: builder != null
? Builder(
builder: (context) => builder!(context, child),
)
: child!,
);
}
}
@override
_InheritedProviderScopeElement<T> createElement() {
return _InheritedProviderScopeElement<T>(this);
}
@override
_CreateInheritedProviderState<T> createState() =>_CreateInheritedProviderState();
6.3 Provider.of
注册监听并获取ChangeNotifier BuildContext->dependOnInheritedElement->InheritedElement->updateDependencies->setDependencies->添加到_dependents(需要监听的Map)中
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,
) {
}
@override
InheritedElement? getElementForInheritedWidgetOfExactType<T extends InheritedWidget>() {
assert(_debugCheckStateIsActiveForAncestorLookup());
final InheritedElement? ancestor = _inheritedWidgets == null ? null : _inheritedWidgets![T];
return ancestor;
}
@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;
}
final Map<Element, Object?> _dependents
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,
);
}
参考资料
|