Flutter Provider Selector

Selector<A, S>

相当于 Consumer 可以通过选择有限数量的值来过滤更新,并在它们没有更改时防止重建。
Selector 将使用 Provider.of 获取一个值,然后将该值传递给 selector。然后,该selector回调的任务是返回一个对象,该对象仅包含builder所需的信息。

Selector 源码:

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,
        );
}

示例:

这里使用了 mixin 混入了 ChangeNotifier,这个类能够帮驻我们自动管理所有听众。
当调用 notifyListeners() 时,它会通知所有监听者进行刷新。

import 'package:flutter/material.dart';

class CountModel with ChangeNotifier {
  int _count = 0;

  int get count => _count;

  void increment() {
    _count++;
    notifyListeners();
  }
}

UI相关代码:
value : 是下面 selector的返回值

 Selector<UserModel, int>(
            builder: (BuildContext context, value, Widget child) {
              return Row(
                children: [
                  child,
                  Text('$value'),
                ],
              );
            },
            selector: (BuildContext context, UserModel userModel) {
              return userModel.count;
            },
            child: Text(['count:'),
          ),

主要记录一下参数相关的东西:

  • A 指的是model , 或者叫provider (指with/extend ChangeNotifier的那个类),示例中的CountModel .
  • S selector参数中的返回类型 , 一般为 model中维护的数据 .
    如例子中的count的类型 int. 也可以是Wdiget, 比如你在这里返回一个Text, 就可以在builder中直接使用
            builder: (BuildContext context, value, Widget child) {
              return Row(
                children: [
                  child,
                  value,
                ],
              );
            },
            selector: (BuildContext context, UserModel userModel) {
              return Text('${userModel.count}');
            },
  • typedef ValueWidgetBuilder<T> = Widget Function(BuildContext context, T value, Widget? child)
    T : selector的返回值的类型 , 其实是ValueWidgetBuilder<S>中的 S.
  • S Function(BuildContext, A) selector
    A : 同上文
  • typedef ShouldRebuild<T> = bool Function(T previous, T next)
    S : 同上文 ,其实是ShouldRebuild<S>? shouldRebuild中的S

理解了以上这些概念,使用的时候就不会懵逼了 .

Selector的好处 :

  • 减少UI重绘的部分, 提升性能 . 当监听到数据变更时, 只会重新调用builder.不会重绘更多UI部分.
  • 默认情况下,Selector通过使用来自包集合的 DeepCollectionEquality 比较Selector的先前和新结果来确定是否需要再次调用builder。(可以通过传递自定义的 shouldRebuild 回调来覆盖此行为。)

猜你喜欢

转载自blog.csdn.net/u011272795/article/details/118165333