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 是什么?什么时候触发?

  • listenWhen 是 BlocListener 的一个可选回调函数,签名如下:
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 过滤)。
  • listenWhen 和 buildWhen 可以搭配使用,实现精细控制。

总结

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

相关推荐
拥小抱6 小时前
Compose 知识点
android
文章永久免费只为良心6 小时前
Web应用安全与防护_第三章_日志文件包含_从一道 CTFshow 题目讲透「日志投毒型 LFI → RCE」:原理、时序陷阱与全变种攻防手册
android·网络安全·渗透测试·漏洞危害·漏洞描述·日志投毒·红队指南
AIsoft_86897 小时前
学术讲座录音如何整理?录音APP可行吗
android·iphone
Patrick在香港9 小时前
一个斜杠,把毫秒变成十几秒
android·数据库·python·性能优化·正则表达式·回溯·redos
海雅达手持终端PDA11 小时前
工业手持终端的“去手机化”演进:看海雅达如何以“同轴扫摄”终结工程妥协,重塑工业PDA新范式
android·物联网·智能手机·硬件工程·能源·制造·iot
booboosui11 小时前
删掉一个住在本机的 agent:8 处要清,顺序不能反
android
hcgeng12 小时前
Android获取崩溃日志
android
aqi0012 小时前
AI编程让鸿蒙开发电子书APP更加快捷
android·华为·harmonyos·鸿蒙·harmony
GY-9312 小时前
【Android】Android Studio 中的协程
android