“ValueNotifier”+“ValueListenableBuilder”是不是适用于 Flutter 中的“许多”小部件?

Posted

技术标签:

【中文标题】“ValueNotifier”+“ValueListenableBuilder”是不是适用于 Flutter 中的“许多”小部件?【英文标题】:Are "ValueNotifier" + "ValueListenableBuilder" suitable for "many" widgets in Flutter?“ValueNotifier”+“ValueListenableBuilder”是否适用于 Flutter 中的“许多”小部件? 【发布时间】:2020-04-18 13:09:38 【问题描述】:

ValueNotifier 可以与一个或多个ValueListenableBuilder 组合以管理状态并简化 UI 的开发。

但是,ValueNotifier 继承自 ChangeNotifier,并且文档指出:

ChangeNotifier 针对少数(一或两个)听众进行了优化。添加和删​​除监听器是 O(N),调度通知是 O(N²)(其中 N 是监听器的数量)

因此,据我了解,让多个 ValueListenableBuilder 监听同一个通知程序并不是最佳做法。

另一方面,the official video presentation 则相反,表示您可以同时更新多个小部件:

我的问题是:

文档和视频不矛盾吗? 为什么通知是 O(N²) 而不是 O(N)? 我应该使用比 ValueNotifier / ValueListenableBuilder 更好的东西吗?

【问题讨论】:

【参考方案1】:

关于通知的复杂性:

阅读source code for ChangeNotifier 查看notifyListeners 方法:在线203 执行for 循环,并为每次迭代调用_listeners.contains

forcontains 都具有 O(N) 复杂度,并且由于在每次迭代中都会调用 contains,所以你知道它为什么是 O(N²)。

我认为视频和文档之间没有矛盾。 当您需要根据ValueNotifier 的值更新几个小部件时,这种方法非常适合小情况。

对于更大的情况,您可以使用InheritedWidget,我认为它甚至适合在应用程序范围的上下文中公开值(请参阅主题,MediaQuery),或者您可以使用 BLoC 方法,它利用 Dart 流。

虽然我已经搜索过,但我没有找到有关建议方法的通知复杂性的具体信息。

我之所以推荐它们,是因为我认为它们更适合复杂的场景,我可以根据我个人使用它们的经验来支持这一点。

通常我使用 BLoC 进行业务逻辑相关的状态管理,使用 InheritedWidget(特别是 provider package)进行 UI 相关的状态管理。

【讨论】:

感谢您的回答。这是引入 O(N²) 复杂性的提交:b00efda(允许在通知期间删除侦听器)。我也在使用 BLoC,但我正在学习如何管理 UI 状态(不涉及业务逻辑),这就是我尝试使用 ValueNotifier 的原因。我可以切换到provider,因为它是官方推荐的。 我不明白的最后一件事:您建议使用InheritedWidget,但我看不出它对通知有何帮助。据我所知,这个小部件有助于共享对 ValueNotifier 对象的“访问”,但假设我希望在值更改时重建 3 个不同的小部件,我仍然需要 3 个 ValueListenableBuiler,这不能解决复杂性问题,对吗? 不,如果使用InheritedWidget,则不需要ValueListenableBuilder。请注意,当您实现自己的InheritedWidget 时,您必须覆盖updateShouldNotify:此方法返回一个布尔值,它可以回答以下问题:“是否应在更改时重建对这个InheritedWidget 的引用的小部件?”如果您的覆盖返回 true,则将重建引用小部件。这是上述方法的文档:api.flutter.dev/flutter/widgets/InheritedWidget/… flutter 改变了 ChangeNotifier 的实现

以上是关于“ValueNotifier”+“ValueListenableBuilder”是不是适用于 Flutter 中的“许多”小部件?的主要内容,如果未能解决你的问题,请参考以下文章

ValueNotifier:在页面构建完成之前更新小部件的文本引发异常

Flutter ValueNotifier 倒计时 局部刷新组件 在StatelessWidget 中刷新倒计时

Flutter ValueNotifier实际开发使用

Flutter 中 ValueNotifier<List<T>> 监听问题解决

ValueNotifier 未处理的异常:类型“String”不是“index”类型“int”的子类型

Inter Widget通讯