Provider原理

简单理解就是通过控制Provider封装中相关widget的rebuild,从而控制InheritedWidget子树下依赖于InheritedWidget的小部件rebuild。相关原理图如下


InheritedWidget.png

Provider.png

如下面代码所示,因为widget创建一次之后在_InheritedProviderScope的child持有,所以后续Provider notifyListeners();的时候不会重新构建Provider的child

# class InheritedProvider
@override
  Widget buildWithChild(BuildContext context, Widget child) {
    assert(
      _builder != null || child != null,
      '$runtimeType used outside of MultiProvider must specify a child',
    );
    return _InheritedProviderScope(
      owner: this,
      child: _builder != null
          ? Builder(
              builder: (context) => _builder(context, child),
            )
          : child,
    );
  }

补充 Selector

///A为provider类型,S是需要使用的provider类里面的某个数据的类型,selector返回需要的S类型的数据,然后在builder中使用该数据
class Selector extends Selector0 {
  /// {@macro provider.selector}
  Selector({
    Key key,
    @required ValueWidgetBuilder builder,
    @required S Function(BuildContext, A) selector,
    ShouldRebuild shouldRebuild,
    Widget child,
  })  : assert(selector != null),
        super(
          key: key,
          shouldRebuild: shouldRebuild,
          builder: builder,
          selector: (context) => selector(context, Provider.of(context)),
          child: child,
        );
}

class Selector0 extends SingleChildStatefulWidget {
@override
  _Selector0State createState() => _Selector0State();
}
class _Selector0State extends SingleChildState> {
  T value;
  Widget cache;
  Widget oldWidget;

  @override
  Widget buildWithChild(BuildContext context, Widget child) {
    final selected = widget.selector(context);

    var shouldInvalidateCache = oldWidget != widget ||
        (widget._shouldRebuild != null && widget._shouldRebuild.call(value, selected)) ||
        (widget._shouldRebuild == null && !const DeepCollectionEquality().equals(value, selected));
    if (shouldInvalidateCache) {
      value = selected;
      oldWidget = widget;
      cache = widget.builder(
        context,
        selected,
        child,
      );
    }
    return cache;
  }
}

你可能感兴趣的:(Provider原理)