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 构建的解耦。

相关推荐
黑码哥4 分钟前
ViewHolder设计模式深度剖析:iOS开发者掌握Android列表性能优化的实战指南
android·ios·性能优化·跨平台开发·viewholder
亓才孓15 分钟前
[JDBC]元数据
android
独行soc27 分钟前
2026年渗透测试面试题总结-17(题目+回答)
android·网络·安全·web安全·渗透测试·安全狮
金融RPA机器人丨实在智能35 分钟前
Android Studio开发App项目进入AI深水区:实在智能Agent引领无代码交互革命
android·人工智能·ai·android studio
科技块儿36 分钟前
利用IP查询在智慧城市交通信号系统中的应用探索
android·tcp/ip·智慧城市
独行soc1 小时前
2026年渗透测试面试题总结-18(题目+回答)
android·网络·安全·web安全·渗透测试·安全狮
ujainu1 小时前
Flutter + OpenHarmony 实现经典打砖块游戏开发实战—— 物理反弹、碰撞检测与关卡系统
flutter·游戏·openharmony·arkanoid·breakout
微祎_1 小时前
构建一个 Flutter 点击速度测试器:深入解析实时交互、性能度量与响应式 UI 设计
flutter·ui·交互
王码码20352 小时前
Flutter for OpenHarmony 实战之基础组件:第二十七篇 BottomSheet — 动态底部弹窗与底部栏菜单
android·flutter·harmonyos
2501_915106322 小时前
app 上架过程,安装包准备、证书与描述文件管理、安装测试、上传
android·ios·小程序·https·uni-app·iphone·webview