flutter-provider学习笔记

简介: flutter-provider学习笔记
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,
        );
}


参考资料
相关文章
|
8月前
|
设计模式 缓存 Dart
Flutter学习笔记&学习资料推荐,15分钟的字节跳动视频面试
Flutter学习笔记&学习资料推荐,15分钟的字节跳动视频面试
|
5天前
|
前端开发 Java 开发工具
【03】完整flutter的APP打包流程-以apk设置图标-包名-签名-APP名-打包流程为例—-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草央千澈 章节内容【03】
【03】完整flutter的APP打包流程-以apk设置图标-包名-签名-APP名-打包流程为例—-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草央千澈 章节内容【03】
【03】完整flutter的APP打包流程-以apk设置图标-包名-签名-APP名-打包流程为例—-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草央千澈 章节内容【03】
|
2天前
|
缓存 前端开发 Android开发
【04】flutter补打包流程的签名过程-APP安卓调试配置-结构化项目目录-完善注册相关页面-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程
【04】flutter补打包流程的签名过程-APP安卓调试配置-结构化项目目录-完善注册相关页面-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程
【04】flutter补打包流程的签名过程-APP安卓调试配置-结构化项目目录-完善注册相关页面-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程
|
3月前
|
Android开发 iOS开发 容器
鸿蒙harmonyos next flutter混合开发之开发FFI plugin
鸿蒙harmonyos next flutter混合开发之开发FFI plugin
|
6天前
|
Dart 前端开发 Android开发
【02】写一个注册页面以及配置打包选项打包安卓apk测试—开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草央千澈
【02】写一个注册页面以及配置打包选项打包安卓apk测试—开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草央千澈
【02】写一个注册页面以及配置打包选项打包安卓apk测试—开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草央千澈
|
7天前
|
Dart 前端开发 架构师
【01】vs-code如何配置flutter环境-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草央千澈-供大大的学习提升
【01】vs-code如何配置flutter环境-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草央千澈-供大大的学习提升
|
6天前
|
JavaScript 前端开发 Linux
flutter开发-figma交互设计图可以转换为flutter源代码-如何将设计图转换为flutter源代码-优雅草央千澈
flutter开发-figma交互设计图可以转换为flutter源代码-如何将设计图转换为flutter源代码-优雅草央千澈
|
2月前
|
开发框架 Dart 前端开发
Flutter 是谷歌推出的一款高效跨平台移动应用开发框架,使用 Dart 语言,具备快速开发、跨平台支持、高性能、热重载及美观界面等特点。
Flutter 是谷歌推出的一款高效跨平台移动应用开发框架,使用 Dart 语言,具备快速开发、跨平台支持、高性能、热重载及美观界面等特点。本文从 Flutter 简介、特点、开发环境搭建、应用架构、组件详解、路由管理、状态管理、与原生代码交互、性能优化、应用发布与部署及未来趋势等方面,全面解析 Flutter 技术,助你掌握这一前沿开发工具。
93 8
|
2月前
|
存储 JavaScript 前端开发
在Flutter开发中,状态管理至关重要。随着应用复杂度的提升,有效管理状态成为挑战
在Flutter开发中,状态管理至关重要。随着应用复杂度的提升,有效管理状态成为挑战。本文介绍了几种常用的状态管理框架,如Provider和Redux,分析了它们的基本原理、优缺点及适用场景,并提供了选择框架的建议和使用实例,旨在帮助开发者提高开发效率和应用性能。
48 4
|
2月前
|
传感器 前端开发 Android开发
在 Flutter 开发中,插件开发与集成至关重要,它能扩展应用功能,满足复杂业务需求
在 Flutter 开发中,插件开发与集成至关重要,它能扩展应用功能,满足复杂业务需求。本文深入探讨了插件开发的基本概念、流程、集成方法、常见类型及开发实例,如相机插件的开发步骤,同时强调了版本兼容性、性能优化等注意事项,并展望了插件开发的未来趋势。
55 2