当前位置: 首页 > news >正文

鸿蒙Flutter ProxyProvider代理Provider:依赖其他Provider的状态


一、ProxyProvider简介

在Flutter开发中,我们经常需要创建依赖其他Provider的Provider。ProxyProvider是Provider库提供的一种特殊Provider,专门用于创建依赖其他Provider的Provider。

ProxyProvider的核心特点:

  • 依赖其他Provider:ProxyProvider可以依赖一个或多个其他Provider
  • 自动更新:当依赖的Provider变化时,ProxyProvider会自动重新计算
  • 支持多依赖:支持ProxyProvider2/3/4等多依赖版本
  • 支持ChangeNotifier:ChangeNotifierProxyProvider用于ChangeNotifier类型
  • previous参数优化:可以使用previous参数避免不必要的重建

二、基本用法

2.1 创建ProxyProvider

MultiProvider(providers:[Provider<String>(create:(_)=>'Hello'),ProxyProvider<String,String>(update:(context,value,previous)=>'$valueWorld!',),],child:Consumer<String>(builder:(context,value,child)=>Text(value),),)

三、ProxyProvider2/3/4

3.1 依赖两个Provider

ProxyProvider2<UserProvider,CartProvider,OrderSummary>(update:(context,user,cart,previous){returnOrderSummary(userName:user.name,totalAmount:cart.totalAmount,itemCount:cart.itemCount,);},)

3.2 依赖三个Provider

ProxyProvider3<UserProvider,CartProvider,CouponProvider,CheckoutData>(update:(context,user,cart,coupon,previous){returnCheckoutData(user:user,cart:cart,discount:coupon.calculateDiscount(cart.totalAmount),);},)

四、ChangeNotifierProxyProvider

4.1 创建依赖其他Provider的ChangeNotifier

MultiProvider(providers:[Provider<ApiService>(create:(_)=>ApiService()),ChangeNotifierProxyProvider<ApiService,DataProvider>(create:(context)=>DataProvider(),update:(context,apiService,dataProvider){returndataProvider!..apiService=apiService;},),],child:constMyApp(),)

4.2 在ChangeNotifier中使用ProxyProvider

classDataProviderextendsChangeNotifier{lateApiService_apiService;List<Item>_items=[];List<Item>getitems=>_items;setapiService(ApiServicevalue){_apiService=value;_loadData();}Future<void>_loadData()async{_items=await_apiService.fetchItems();notifyListeners();}}

五、FutureProxyProvider

5.1 创建依赖其他Provider的FutureProvider

MultiProvider(providers:[Provider<String>(create:(_)=>'api_key'),FutureProxyProvider<String,User>(update:(context,apiKey,previous){returnfetchUser(apiKey);},initialData:User.empty(),),],child:constUserPage(),)

六、StreamProxyProvider

6.1 创建依赖其他Provider的StreamProvider

MultiProvider(providers:[Provider<String>(create:(_)=>'channel_id'),StreamProxyProvider<String,List<Message>>(update:(context,channelId,previous){returnsubscribeToChannel(channelId);},initialData:const[],),],child:constChatPage(),)

七、previous参数的使用

7.1 使用previous参数优化性能

ProxyProvider<UserProvider,String>(update:(context,user,previous){if(previous!=null&&previous.contains(user.name)){returnprevious;}return'欢迎回来,${user.name}!';},)

7.2 previous参数的作用

  • previous参数:表示上一次计算的结果
  • 优化性能:可以通过比较previous和当前值,避免不必要的重建
  • 适用场景:当计算结果可能不变时,可以使用previous参数优化

八、完整示例

8.1 创建用户Provider

classUserProviderextendsChangeNotifier{String_name='张三';Stringgetname=>_name;voidupdateName(StringnewName){_name=newName;notifyListeners();}}

8.2 创建购物车Provider

classCartProviderextendsChangeNotifier{double _totalAmount=0;int _itemCount=0;doublegettotalAmount=>_totalAmount;intgetitemCount=>_itemCount;voidaddItem(double price){_totalAmount+=price;_itemCount++;notifyListeners();}}

8.3 创建订单汇总数据类

classOrderSummary{finalStringuserName;finaldouble totalAmount;finalint itemCount;constOrderSummary({requiredthis.userName,requiredthis.totalAmount,requiredthis.itemCount,});}

8.4 创建ProxyProvider页面

classProxyProviderPageextendsStatelessWidget{constProxyProviderPage({super.key});@overrideWidgetbuild(BuildContextcontext){returnMultiProvider(providers:[ChangeNotifierProvider(create:(_)=>UserProvider()),ChangeNotifierProvider(create:(_)=>CartProvider()),ProxyProvider2<UserProvider,CartProvider,OrderSummary>(update:(context,user,cart,previous){returnOrderSummary(userName:user.name,totalAmount:cart.totalAmount,itemCount:cart.itemCount,);},),],child:Scaffold(appBar:AppBar(title:constText('ProxyProvider演示')),body:ListView(padding:constEdgeInsets.all(16),children:[_buildSection('基本用法',_basicUsage()),_buildSection('多依赖ProxyProvider',_multiDependencyUsage()),_buildSection('ChangeNotifierProxyProvider',_changeNotifierProxyUsage()),_buildSection('previous参数优化',_previousParameterUsage()),],),),);}Widget_buildSection(Stringtitle,Widgetcontent){returnCard(margin:constEdgeInsets.only(bottom:16),child:Padding(padding:constEdgeInsets.all(16),child:Column(crossAxisAlignment:CrossAxisAlignment.start,children:[Text(title,style:constTextStyle(fontSize:18,fontWeight:FontWeight.bold)),constSizedBox(height:12),content,],),),);}Widget_basicUsage(){returnConsumer<OrderSummary>(builder:(context,summary,child){returnColumn(children:[Text('用户名:${summary.userName}',style:constTextStyle(fontSize:16)),Text('总金额: ¥${summary.totalAmount.toStringAsFixed(2)}',style:constTextStyle(fontSize:16)),Text('商品数量:${summary.itemCount}',style:constTextStyle(fontSize:16)),],);},);}Widget_multiDependencyUsage(){returnColumn(children:[TextField(decoration:constInputDecoration(labelText:'输入用户名'),onSubmitted:(value){context.read<UserProvider>().updateName(value);},),constSizedBox(height:16),ElevatedButton(onPressed:()=>context.read<CartProvider>().addItem(19.9),child:constText('添加商品(¥19.9)'),),],);}}

8.5 代码解析

在这个演示页面中:

  1. 基本用法:使用ProxyProvider2创建依赖UserProvider和CartProvider的OrderSummary
  2. 多依赖ProxyProvider:展示了如何依赖多个Provider
  3. ChangeNotifierProxyProvider:展示了如何创建依赖其他Provider的ChangeNotifier
  4. previous参数优化:展示了如何使用previous参数优化性能

九、ProxyProvider类型总结

类型用途
ProxyProvider创建依赖一个Provider的不可变Provider
ProxyProvider2/3/4创建依赖多个Provider的不可变Provider
ChangeNotifierProxyProvider创建依赖其他Provider的ChangeNotifier
FutureProxyProvider创建依赖其他Provider的FutureProvider
StreamProxyProvider创建依赖其他Provider的StreamProvider

十、关键要点

10.1 ProxyProvider用于创建依赖其他Provider的Provider

ProxyProvider适合创建依赖其他Provider的Provider,当依赖的Provider变化时,自动重新计算。

10.2 支持ProxyProvider2/3/4等多依赖版本

ProxyProvider支持多个依赖,可以根据需要选择不同的版本。

10.3 ChangeNotifierProxyProvider用于ChangeNotifier类型

对于ChangeNotifier类型,使用ChangeNotifierProxyProvider而不是普通的ProxyProvider。

10.4 previous参数可以用于优化,避免不必要的重建

通过比较previous和当前值,可以避免不必要的重建,提高性能。

10.5 当依赖的Provider变化时,ProxyProvider会自动重新计算

ProxyProvider会自动监听依赖的Provider变化,当依赖变化时重新计算。

十一、常见错误

11.1 错误:依赖的Provider未声明

MultiProvider(providers:[// 错误:依赖的Provider未声明ProxyProvider<String,String>(update:(context,value,previous)=>'$valueWorld!',),],child:constMyApp(),)

正确:先声明依赖的Provider

MultiProvider(providers:[Provider<String>(create:(_)=>'Hello'),ProxyProvider<String,String>(update:(context,value,previous)=>'$valueWorld!',),],child:constMyApp(),)

11.2 错误:依赖的Provider顺序错误

MultiProvider(providers:[// 错误:ProxyProvider依赖UserProvider,但UserProvider在后面声明ProxyProvider<UserProvider,String>(update:(context,user,previous)=>user.name,),ChangeNotifierProvider(create:(_)=>UserProvider()),],child:constMyApp(),)

正确:按依赖顺序声明Provider

MultiProvider(providers:[ChangeNotifierProvider(create:(_)=>UserProvider()),// 正确:UserProvider在ProxyProvider之前声明ProxyProvider<UserProvider,String>(update:(context,user,previous)=>user.name,),],child:constMyApp(),)

11.3 错误:忘记处理previous参数

// 错误:每次都重新创建对象,即使数据没有变化ProxyProvider<UserProvider,OrderSummary>(update:(context,user,previous){returnOrderSummary(userName:user.name);},)

正确:使用previous参数优化

// 正确:只有当用户名变化时才重新创建对象ProxyProvider<UserProvider,OrderSummary>(update:(context,user,previous){if(previous!=null&&previous.userName==user.name){returnprevious;}returnOrderSummary(userName:user.name);},)

十二、最佳实践

12.1 合理划分依赖关系

将相关的Provider组织在一起,清晰地表达依赖关系:

MultiProvider(providers:[Provider<ApiService>(create:(_)=>ApiService()),Provider<StorageService>(create:(_)=>StorageService()),ChangeNotifierProxyProvider2<ApiService,StorageService,DataProvider>(create:(context)=>DataProvider(),update:(context,api,storage,data){returndata!..updateDependencies(api,storage);},),],child:constMyApp(),)

12.2 使用immutable数据类

对于ProxyProvider的输出,使用immutable数据类可以提高性能:

@immutableclassOrderSummary{finalStringuserName;finaldouble totalAmount;constOrderSummary({requiredthis.userName,requiredthis.totalAmount,});}

12.3 使用previous参数优化性能

当计算结果可能不变时,使用previous参数避免不必要的重建:

ProxyProvider<UserProvider,String>(update:(context,user,previous){if(previous!=null&&previous==user.name){returnprevious;}return'欢迎,${user.name}!';},)

12.4 避免过度使用ProxyProvider

不要为简单的计算使用ProxyProvider,只有当确实需要依赖其他Provider时才使用:

// 不推荐:简单计算不需要ProxyProviderProxyProvider<String,String>(update:(context,value,previous)=>value.toUpperCase(),)// 推荐:直接在Widget中计算Consumer<String>(builder:(context,value,child)=>Text(value.toUpperCase()),)

十三、总结

ProxyProvider是创建依赖其他Provider的Provider的强大工具,它提供了以下功能:

  • 依赖一个或多个其他Provider
  • 当依赖的Provider变化时自动重新计算
  • 支持多种类型的ProxyProvider
  • previous参数可以优化性能

在实际开发中,建议遵循以下原则:

  1. 合理划分依赖关系
  2. 使用immutable数据类
  3. 使用previous参数优化性能
  4. 避免过度使用ProxyProvider
  5. 按依赖顺序声明Provider

希望本文能帮助你掌握ProxyProvider的使用,并在实际项目中正确处理依赖关系!

http://www.jsqmd.com/news/1229510/

相关文章:

  • iOS激活锁绕过工具applera1n:技术原理与实用指南
  • C#模式匹配实战:8大技巧优化代码逻辑
  • Claude Desktop Linux终极指南:5分钟搞定跨发行版AI助手部署
  • 2026南昌贵金属回收排名 TOP5 国家资质黄金回收、铂金回收、白银回收,上门回收无套路靠谱 联系方式推荐 - 中安检金银铂钻回收
  • java学习交流
  • 雅马哈乐器滞销事件背后的行业变革与技术解析
  • 2026杭州别墅阳光房改造多家行业标杆厂家考察避坑 - 中国远见品牌企业资讯
  • 从Excel公式到自动决策:AI办公工具进阶路线图(附:21个真实场景Prompt模板+权限配置Checklist)
  • SpringBoot+Vue全栈项目实战:家政服务平台从部署到二次开发指南
  • 【Springboot毕设全套源码+文档】基于springboot旧物回收商城系统的设计与实现(丰富项目+远程调试+讲解+定制)
  • 深入解析CPTS事件FIFO:高精度时间同步的硬件机制与软件实践
  • 2026九江贵金属回收排名 TOP5 国家资质黄金回收、铂金回收、白银回收,上门回收无套路靠谱 联系方式推荐 - 中安检金银铂钻回收
  • Krakatau字节码工程实践:深度解析Java字节码汇编与反汇编技术
  • ROCm GPU内存管理终极指南:从零到精通的高性能内存优化策略
  • 福州高定木作避坑:全屋定制最容易踩的 3 个隐形陷阱
  • 食品饮料经销商如何通过订货小程序提高客户下单效率
  • 2026年7月洛阳靠谱的刑事辩护律师推荐指南:焦艺昊拆解跑分、醉驾、贷款诈骗案件司法处置核心实务要点 - 十大排行榜推荐
  • 2026企业官网GEO怎么优化?三阶方法提收录,零成本提30%抓取权重附自查清单
  • GitHub 全网最全使用指南:从入门到榨干
  • SpringBoot集成bpmn-js流程设计器:前端可视化工作流开发实战
  • AI数据分析效率翻倍的7个隐藏技巧:90%的数据工程师至今未掌握的自动化工作流
  • tkDNN性能调优秘籍:如何将Jetson Xavier NX的推理速度提升3倍
  • AI教材写作秘籍:掌握这些技巧,用AI快速完成高校专业教材编写!
  • 本地黄金回收怎么选,天津正规靠谱高价门店推荐 - 日常比对手册
  • InSPyReNet项目深度解析:图像金字塔结构如何革新显著目标检测
  • 4小时完成8xA100实验:ddpo-pytorch的高性能训练策略与配置分享
  • 循环工程:从代码编写到自动化系统设计的范式转变
  • 写完歌可以直接发行的平台:7款AI音乐创作发行平台怎么选
  • 5个Loop窗口管理快捷键:让你的Mac效率翻倍的终极秘籍
  • 2026 大连西岗区上门回收名表实测,易奢福同城极速上门当场结算 - 肉松卷