ChangeNotifierProvider 与 ChangeNotifierProvider.value

Avn*_*mar 27 provider frameworks state-management flutter

我对这个框架很陌生,并且使用我遇到的提供程序包进行状态管理ChangeNotifierProviderChangeNotifierProvider.value,但我无法区分它们的用例。

我曾用ChangeNotifierProvider代替ChangeNotifierProvider.value,但它没有按预期工作。

Sur*_*gch 57

让我们分步骤进行。

什么是变更通知程序?

扩展的类ChangeNotifier可以随时调用该类中的notifyListeners()数据已更新,并且您希望让侦听器知道该更新。这通常在视图模型中完成,以通知 UI 基于新数据重建布局。

下面是一个例子:

class MyChangeNotifier extends ChangeNotifier {
  int _counter = 0;
  int get counter => _counter;

  void increment() {
    _counter++;
    notifyListeners();
  }
}
Run Code Online (Sandbox Code Playgroud)

我在构建 Flutter 应用程序的初学者指南中写了更多关于此的内容

什么是 ChangeNotifierProvider?

ChangeNotifierProviderProvider 包多种类型的提供者之一。如果您已经有一个 ChangeNotifier 类(如上面的那个),那么您可以使用它来将它提供给您在 UI 布局中需要它的地方。ChangeNotifierProvider

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return ChangeNotifierProvider<MyChangeNotifier>(        // define it
      create: (context) => MyChangeNotifier(),              // create it
      child: MaterialApp(
        ...

          child: Consumer<MyChangeNotifier>(                // get it
            builder: (context, myChangeNotifier, child) {
              ...
                  myChangeNotifier.increment();             // use it
Run Code Online (Sandbox Code Playgroud)

请特别注意,在此行中创建了 MyChangeNotifier 类的新实例:

create: (context) => MyChangeNotifier(),
Run Code Online (Sandbox Code Playgroud)

这是在第一次构建小部件时完成一次,而不是在随后的重建中完成。

什么是 ChangeNotifierProvider.value 呢?

使用ChangeNotifierProvider.value,如果你已经创建的实例ChangeNotifier类。如果你已经初始化您的这种情况可能发生ChangeNotifier在类initState()的方法StatefulWidgetState类。

在这种情况下,您不会想要创建一个全新的实例,ChangeNotifier因为您会浪费您已经完成的任何初始化工作。使用ChangeNotifierProvider.value构造函数允许您提供预先创建的ChangeNotifier值。

class _MyWidgeState extends State<MyWidge> {

  MyChangeNotifier myChangeNotifier;

  @override
  void initState() {
    myChangeNotifier = MyChangeNotifier();
    myChangeNotifier.doSomeInitializationWork();
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return ChangeNotifierProvider<MyChangeNotifier>.value(
      value: myChangeNotifier,                           // <-- important part
      child: ... 
Run Code Online (Sandbox Code Playgroud)

特别注意这里不是create参数,而是value参数。那就是你传入你的ChangeNotifier类实例的地方。同样,不要尝试在那里创建新实例。

您还可以在官方文档中找到其用法ChangeNotifierProviderChangeNotifierProvider.value描述:https : //pub.dev/packages/provider#exposing-a-value

  • 我希望 stackoverflow 上的所有答案都像这个一样写得好。 (5认同)

tim*_*tim 6

官方文档有帮助吗?

使用 ChangeNotifierProvider.value 来提供现有的ChangeNotifier

ChangeNotifierProvider.value(
  value: variable,
  child: ...
)
Run Code Online (Sandbox Code Playgroud)

不要ChangeNotifier使用默认构造函数重用现有的。

ChangeNotifierProvider(
  builder: (_) => variable,   
  child: ... 
)
Run Code Online (Sandbox Code Playgroud)

另请查看作者关于此的Github 问题


Zee*_*ari 5

ValueNotifier 和 ChangeNotifier 密切相关。

事实上,ValueNotifier是ChangeNotifier的子类,它实现了ValueListenable。

这是Flutter SDK中ValueNotifier的实现:

/// A [ChangeNotifier] that holds a single value.
///
/// When [value] is replaced with something that is not equal to the old
/// value as evaluated by the equality operator ==, this class notifies its
/// listeners.
class ValueNotifier<T> extends ChangeNotifier implements ValueListenable<T> {
  /// Creates a [ChangeNotifier] that wraps this value.
  ValueNotifier(this._value);

  /// The current value stored in this notifier.
  ///
  /// When the value is replaced with something that is not equal to the old
  /// value as evaluated by the equality operator ==, this class notifies its
  /// listeners.
  @override
  T get value => _value;
  T _value;
  set value(T newValue) {
    if (_value == newValue)
      return;
    _value = newValue;
    notifyListeners();
  }

  @override
  String toString() => '${describeIdentity(this)}($value)';
}
Run Code Online (Sandbox Code Playgroud)

那么,我们什么时候应该使用 ValueNotifier 和 ChangeNotifier 呢?

如果您需要在简单值更改时重建小部件,请使用 ValueNotifier。如果您希望在调用 notificationListeners() 时获得更多控制,请使用 ChangeNotifier。