Flutter Provider 用法总结(更新中...)

Flutter Provider 用法总结(含 ChangeNotifierProvider、Consumer、ChangeNotifierProxyProvider, BlocListener, BlocBuilder)


1. ChangeNotifierProvider

  • ChangeNotifierProvider<T> 是最常用的 Provider,作用是在 Widget 树中提供一个 T 类型(通常为 ChangeNotifier)的实例,供其子 Widget 访问和监听。
  • 用法示例:
dart 复制代码
ChangeNotifierProvider<SkinSelectNotifier>(
  create: (_) => SkinSelectNotifier(widget.vehicle),
  child: ...
)
  • 上面代码会用 widget.vehicle 创建一个新的 SkinSelectNotifier 实例,并将其注入到子 Widget 树中。

2. Consumer

  • Consumer<T> 是 Provider 体系中用于监听并响应 T 类型 Provider 状态变化的 Widget。
  • 只要 Provider 中的数据有变化,builder 就会自动重建。
  • 用法示例:
dart 复制代码
Consumer<SkinSelectNotifier>(
  builder: (_, value, __) {
    // value 就是最新的 SkinSelectNotifier 实例
    // 只要 SkinSelectNotifier.notifyListeners 被调用,builder 就会刷新
  }
)

3. ChangeNotifierProxyProvider

3.1 作用

  • ChangeNotifierProxyProvider<A, B> 用于创建一个 B 类型(ChangeNotifier),并让它可以依赖于另一个 Provider A 的变化。
  • 当 A 发生变化时,B 可以自动获得最新的 A 实例,及时更新自身状态。

3.2 create 和 update 的区别

  • create:首次在 Widget 树中创建 B(ChangeNotifier)实例时调用。只执行一次。
  • update:每当 A(依赖的 Provider)发生变化,或 Provider 热重载/依赖变化时都会被调用。会多次执行。

3.3 推荐写法

dart 复制代码
ChangeNotifierProxyProvider<MyModel, MyChangeNotifier>(
  create: (_) => MyChangeNotifier(),
  update: (_, myModel, myNotifier) => myNotifier..update(myModel),
)
  • 解释
    • create 只负责实例化 MyChangeNotifier。
    • update 保证每次 MyModel 变化时,将最新的 MyModel 注入 MyChangeNotifier,并复用旧实例。
⚠️ 注意事项
  • 不要update 内直接 new 出新的 B,否则之前的数据和状态会丢失。
  • 推荐在 B 内部实现 update 方法,用于同步依赖变化。

4. 应用场景举例

  • 如果你的 ChangeNotifier 需要依赖于别的 Provider(如用户信息、配置、全局事件流),优先使用 ChangeNotifierProxyProvider
  • 如果只是需要一个简单的可变状态管理,直接用 ChangeNotifierProvider 即可。

5. BlocListener 的 listenWhen 与 BlocBuilder 的关系总结

5.1 listenWhen 是什么?什么时候触发?

  • listenWhenBlocListener 的一个可选回调函数,签名如下:
dart 复制代码
bool listenWhen(previous, current)
  • 每当 Bloc 的状态发生变化时,listenWhen 会被调用一次,传入前一个状态 previous 和当前状态 current
  • 若返回 true,则会执行 listener 回调。
  • 若返回 false,则不执行。

5.2 listenWhen 的用途

用于过滤监听条件,避免每次状态变化都触发副作用,只在关心的状态变化时执行。例如:

dart 复制代码
listenWhen: (previous, current) {
  final isActualLogin = previous.user == null && current.user != null;
  final shouldListen = isActualLogin && (current.action is LoginAction);
  return shouldListen || previous != current;
}

表示:

  • 用户从未登录到已登录,并且 action 是 LoginAction 时触发
  • 或者状态有变化时触发

5.3 返回 true / false 会怎样?

  • 返回 true:执行 listener: (context, state) { ... }
  • 返回 false:不会执行 listener

5.4 BlocListener 和 BlocBuilder 的区别与关系

对象 作用 是否重建 UI 是否执行副作用 有条件过滤功能
BlocListener 执行副作用(如导航) 使用 listenWhen
BlocBuilder 构建 UI 使用 buildWhen
  • BlocListener 不负责 UI 构建,只在特定状态变化时做出响应。
  • BlocBuilder 始终对状态变化做出响应(除非使用 buildWhen 过滤)。
  • listenWhenbuildWhen 可以搭配使用,实现精细控制。

总结

  • listenWhen 用于决定 BlocListener 的 listener 是否触发。
  • 返回 true 会执行副作用逻辑,false 不执行。
  • BlocBuilder 总是响应 Bloc 状态变化,和 listenWhen 无关,若要过滤 UI 重建需使用 buildWhen。
  • 二者搭配使用能实现副作用处理和 UI 构建的解耦。

相关推荐
GitLqr14 小时前
Flutter 3.44 插件内置 Kotlin (KGP) 双向兼容适配指南
android·flutter·dart
随遇丿而安18 小时前
第11周:Activity 跳转与传值 + 跳转优化
android
私人珍藏库19 小时前
[Android] BBLL 开源第三方B哩电视TV端
android·app·生活·工具·多功能
杉氧1 天前
跨平台资源管理:一套代码如何搞定 Android、iOS 和 Web 的图片与多语言?
android·架构·android jetpack
安卓修改大师1 天前
安卓修改大师实战:从反编译到定制的完整APK修改指南
android
柚鸥ASO优化1 天前
安卓APP推广的“降本增效”密码:守好商店内,打好商店外
android·aso优化
我是一颗柠檬1 天前
【Java项目技术亮点】EXPLAIN深度分析与慢查询治理
android·java·开发语言
Android-Flutter1 天前
android compose shadow 阴影 使用
android·kotlin·compose
帅次1 天前
Android 高级工程师面试:Java 多线程与并发 近1年高频追问 22 题
android·java·面试
2501_943782351 天前
【共创季稿事节】摩斯电码转换器:编码表与双向转换的实现
android·华为·鸿蒙·鸿蒙系统