前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Flutter Provider-Selector源码解析

Flutter Provider-Selector源码解析

作者头像
用户4458175
发布2022-04-15 15:03:56
8420
发布2022-04-15 15:03:56
举报
文章被收录于专栏:andy的小窝

本文我们来分析一下Provider中的Selector实现。Selector是我们Provider提供给我们实现条件刷新的组件,同样上个Demo演示。还是一样的Counter状态类。

代码语言:javascript
复制
class Counter with ChangeNotifier {
  int _count = 0;

  int get count => _count;

  void increment() {
    _count++;
    notifyListeners();
  }
}
代码语言:javascript
复制
ChangeNotifierProvider(
  create: (context) => Counter(),
  builder: (context, child) {
    return Selector<Counter, int>(
      selector: (context, counter) => counter.count,
      builder: (_, data, __) {
        return Text('$data');
      },
    );
  },
)

Selector类里有Selector、Selector2、Selector3…,这是相对于需要Select多少个状态类数量。这里我们只需要选择Counter一个状态类里面的数据,所以我们只使用Selector即可。Selector、Selector2等都是继承自Selector0这个widget。

代码语言:javascript
复制
class Selector<A, S> extends Selector0<S> {
  /// {@macro provider.selector}
  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,
        );
}

在父类Selector0的_Selector0State中buildWithChild,widget.selector(context)使用了子类传过来的selector调用了Provider.of(context),创建监听。那他是怎么做到指定条件刷新呢。在_Selector0State中会创建缓存旧Widget-cache、旧数据value,然后会判断widget是否相同、shouldRebuild条件、DeepCollectionEquality对比来判断是否需要更新组件。就这样实现了条件刷新widget。

代码语言:javascript
复制
class _Selector0State<T> extends SingleChildState<Selector0<T>> {
  T? value;
  Widget? cache;
  Widget? oldWidget;

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

    final shouldInvalidateCache = oldWidget != widget ||
        (widget._shouldRebuild != null &&
            widget._shouldRebuild!(value as T, selected)) ||
        (widget._shouldRebuild == null &&
            !const DeepCollectionEquality().equals(value, selected));
    if (shouldInvalidateCache) {
      value = selected;
      oldWidget = widget;
      cache = widget.builder(
        context,
        selected,
        child,
      );
    }
    return cache!;
  }
  ...
}
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022年4月14日,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档