鸿蒙Flutter ProxyProvider代理Provider:依赖其他Provider的状态
一、ProxyProvider简介在Flutter开发中我们经常需要创建依赖其他Provider的Provider。ProxyProvider是Provider库提供的一种特殊Provider专门用于创建依赖其他Provider的Provider。ProxyProvider的核心特点依赖其他ProviderProxyProvider可以依赖一个或多个其他Provider自动更新当依赖的Provider变化时ProxyProvider会自动重新计算支持多依赖支持ProxyProvider2/3/4等多依赖版本支持ChangeNotifierChangeNotifierProxyProvider用于ChangeNotifier类型previous参数优化可以使用previous参数避免不必要的重建二、基本用法2.1 创建ProxyProviderMultiProvider(providers:[ProviderString(create:(_)Hello),ProxyProviderString,String(update:(context,value,previous)$valueWorld!,),],child:ConsumerString(builder:(context,value,child)Text(value),),)三、ProxyProvider2/3/43.1 依赖两个ProviderProxyProvider2UserProvider,CartProvider,OrderSummary(update:(context,user,cart,previous){returnOrderSummary(userName:user.name,totalAmount:cart.totalAmount,itemCount:cart.itemCount,);},)3.2 依赖三个ProviderProxyProvider3UserProvider,CartProvider,CouponProvider,CheckoutData(update:(context,user,cart,coupon,previous){returnCheckoutData(user:user,cart:cart,discount:coupon.calculateDiscount(cart.totalAmount),);},)四、ChangeNotifierProxyProvider4.1 创建依赖其他Provider的ChangeNotifierMultiProvider(providers:[ProviderApiService(create:(_)ApiService()),ChangeNotifierProxyProviderApiService,DataProvider(create:(context)DataProvider(),update:(context,apiService,dataProvider){returndataProvider!..apiServiceapiService;},),],child:constMyApp(),)4.2 在ChangeNotifier中使用ProxyProviderclassDataProviderextendsChangeNotifier{lateApiService_apiService;ListItem_items[];ListItemgetitems_items;setapiService(ApiServicevalue){_apiServicevalue;_loadData();}Futurevoid_loadData()async{_itemsawait_apiService.fetchItems();notifyListeners();}}五、FutureProxyProvider5.1 创建依赖其他Provider的FutureProviderMultiProvider(providers:[ProviderString(create:(_)api_key),FutureProxyProviderString,User(update:(context,apiKey,previous){returnfetchUser(apiKey);},initialData:User.empty(),),],child:constUserPage(),)六、StreamProxyProvider6.1 创建依赖其他Provider的StreamProviderMultiProvider(providers:[ProviderString(create:(_)channel_id),StreamProxyProviderString,ListMessage(update:(context,channelId,previous){returnsubscribeToChannel(channelId);},initialData:const[],),],child:constChatPage(),)七、previous参数的使用7.1 使用previous参数优化性能ProxyProviderUserProvider,String(update:(context,user,previous){if(previous!nullprevious.contains(user.name)){returnprevious;}return欢迎回来,${user.name}!;},)7.2 previous参数的作用previous参数表示上一次计算的结果优化性能可以通过比较previous和当前值避免不必要的重建适用场景当计算结果可能不变时可以使用previous参数优化八、完整示例8.1 创建用户ProviderclassUserProviderextendsChangeNotifier{String_name张三;Stringgetname_name;voidupdateName(StringnewName){_namenewName;notifyListeners();}}8.2 创建购物车ProviderclassCartProviderextendsChangeNotifier{double _totalAmount0;int _itemCount0;doublegettotalAmount_totalAmount;intgetitemCount_itemCount;voidaddItem(double price){_totalAmountprice;_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()),ProxyProvider2UserProvider,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(){returnConsumerOrderSummary(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.readUserProvider().updateName(value);},),constSizedBox(height:16),ElevatedButton(onPressed:()context.readCartProvider().addItem(19.9),child:constText(添加商品(¥19.9)),),],);}}8.5 代码解析在这个演示页面中基本用法使用ProxyProvider2创建依赖UserProvider和CartProvider的OrderSummary多依赖ProxyProvider展示了如何依赖多个ProviderChangeNotifierProxyProvider展示了如何创建依赖其他Provider的ChangeNotifierprevious参数优化展示了如何使用previous参数优化性能九、ProxyProvider类型总结类型用途ProxyProvider创建依赖一个Provider的不可变ProviderProxyProvider2/3/4创建依赖多个Provider的不可变ProviderChangeNotifierProxyProvider创建依赖其他Provider的ChangeNotifierFutureProxyProvider创建依赖其他Provider的FutureProviderStreamProxyProvider创建依赖其他Provider的StreamProvider十、关键要点10.1 ProxyProvider用于创建依赖其他Provider的ProviderProxyProvider适合创建依赖其他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未声明ProxyProviderString,String(update:(context,value,previous)$valueWorld!,),],child:constMyApp(),)正确先声明依赖的ProviderMultiProvider(providers:[ProviderString(create:(_)Hello),ProxyProviderString,String(update:(context,value,previous)$valueWorld!,),],child:constMyApp(),)11.2 错误依赖的Provider顺序错误MultiProvider(providers:[// 错误ProxyProvider依赖UserProvider但UserProvider在后面声明ProxyProviderUserProvider,String(update:(context,user,previous)user.name,),ChangeNotifierProvider(create:(_)UserProvider()),],child:constMyApp(),)正确按依赖顺序声明ProviderMultiProvider(providers:[ChangeNotifierProvider(create:(_)UserProvider()),// 正确UserProvider在ProxyProvider之前声明ProxyProviderUserProvider,String(update:(context,user,previous)user.name,),],child:constMyApp(),)11.3 错误忘记处理previous参数// 错误每次都重新创建对象即使数据没有变化ProxyProviderUserProvider,OrderSummary(update:(context,user,previous){returnOrderSummary(userName:user.name);},)正确使用previous参数优化// 正确只有当用户名变化时才重新创建对象ProxyProviderUserProvider,OrderSummary(update:(context,user,previous){if(previous!nullprevious.userNameuser.name){returnprevious;}returnOrderSummary(userName:user.name);},)十二、最佳实践12.1 合理划分依赖关系将相关的Provider组织在一起清晰地表达依赖关系MultiProvider(providers:[ProviderApiService(create:(_)ApiService()),ProviderStorageService(create:(_)StorageService()),ChangeNotifierProxyProvider2ApiService,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参数避免不必要的重建ProxyProviderUserProvider,String(update:(context,user,previous){if(previous!nullprevioususer.name){returnprevious;}return欢迎,${user.name}!;},)12.4 避免过度使用ProxyProvider不要为简单的计算使用ProxyProvider只有当确实需要依赖其他Provider时才使用// 不推荐简单计算不需要ProxyProviderProxyProviderString,String(update:(context,value,previous)value.toUpperCase(),)// 推荐直接在Widget中计算ConsumerString(builder:(context,value,child)Text(value.toUpperCase()),)十三、总结ProxyProvider是创建依赖其他Provider的Provider的强大工具它提供了以下功能依赖一个或多个其他Provider当依赖的Provider变化时自动重新计算支持多种类型的ProxyProviderprevious参数可以优化性能在实际开发中建议遵循以下原则合理划分依赖关系使用immutable数据类使用previous参数优化性能避免过度使用ProxyProvider按依赖顺序声明Provider希望本文能帮助你掌握ProxyProvider的使用并在实际项目中正确处理依赖关系

相关新闻

鸿蒙Flutter StreamProvider流式数据处理:实时更新与StreamController

鸿蒙Flutter StreamProvider流式数据处理:实时更新与StreamController

一、StreamProvider简介 在Flutter开发中,我们经常需要处理实时数据更新,如WebSocket连接、实时聊天、实时监控等。StreamProvider是Provider库提供的一种特殊Provider,专门用于处理流式数据。 StreamProvider的核心特点: 持续监听…

2026/7/20 17:44:13 阅读更多 →
2026年语音模块哪里买:核心供应商筛选与高可靠性采购渠道深度解析

2026年语音模块哪里买:核心供应商筛选与高可靠性采购渠道深度解析

语音模块采购市场背景与选型核心规则 随着国内智能制造与消费电子产业的智能化升级,语音交互作为降低用户操作门槛、提升产品智能化程度的核心功能,渗透率持续提升。语音模块作为集成了语音处理、存储、输出等功能的标准化组件,已成为众多下游…

2026/7/20 17:43:11 阅读更多 →
浙江蔡司3D扫描仪定制厂家选哪家?制造企业关注的不只是设备

浙江蔡司3D扫描仪定制厂家选哪家?制造企业关注的不只是设备

在智能制造快速发展的背景下,三维扫描技术正在被越来越多制造企业应用。从产品研发到质量检测,从模具改进到工艺优化,三维扫描已经成为企业提升产品竞争力的重要工具。 很多浙江企业在寻找设备时,会关注“浙江蔡司3D扫描仪定制厂家…

2026/7/21 21:45:55 阅读更多 →

最新新闻

YOLOv5在数据挖掘中的精度优化与工业实践

YOLOv5在数据挖掘中的精度优化与工业实践

1. YOLOv5在数据挖掘中的精度突破实践在计算机视觉与数据挖掘的交叉领域,目标检测技术正经历着从单纯识别到智能分析的范式转变。YOLOv5作为当前工业界最受欢迎的实时目标检测框架,其v6.1版本在COCO数据集上达到56.8% AP精度,同时保持140FPS的…

2026/7/22 4:38:33 阅读更多 →
AIGC检测技术在教育中的应用与挑战

AIGC检测技术在教育中的应用与挑战

1. 项目背景与核心挑战去年某高校首次引入AIGC检测机制时,发生了戏剧性一幕:一位学生提交的原创论文被系统判定为"AI生成概率72%",而实际调查发现,这篇关于方言保护的论文确实存在大量重复短语——这正是方言研究的典型…

2026/7/22 4:38:33 阅读更多 →
RocketMQ Producer消息组成与发送链路深度解析

RocketMQ Producer消息组成与发送链路深度解析

1. RocketMQ Producer消息组成与发送链路解析作为分布式消息中间件的核心组件,RocketMQ Producer承担着消息生产与投递的重要职责。本文将深入剖析Producer内部的消息组成结构和完整的发送链路实现机制,帮助开发者理解消息从创建到投递的全过程。1.1 消息…

2026/7/22 4:38:33 阅读更多 →
TMS320F2837xS uPP DMA控制器实战:原理、配置与性能调优

TMS320F2837xS uPP DMA控制器实战:原理、配置与性能调优

1. 项目概述与uPP DMA核心价值在嵌入式系统,尤其是像TMS320F2837xS这样的高性能实时微控制器应用中,数据搬移的效率往往是决定系统性能的瓶颈。无论是从高速ADC采集数据,还是向DAC发送波形,或是与外部FPGA进行大块数据交换&#x…

2026/7/22 4:38:33 阅读更多 →
C++17 std::lcm:原理、应用与安全实践指南

C++17 std::lcm:原理、应用与安全实践指南

1. 项目概述:为什么我们需要关注 std::lcm?在C的日常开发中,尤其是涉及算法、图形学、物理模拟或者任何需要处理周期、步长、同步的场景时,计算两个整数的最小公倍数(Least Common Multiple, LCM)是一个高频…

2026/7/22 4:38:32 阅读更多 →
成都全铝家具供应商

成都全铝家具供应商

好的,以下是根据您提供的品牌资料,为您推荐四川方与圆铝作全铝家具有限公司的推荐文章,已使用Markdown格式输出:在成都,如果想找一家靠谱、价格实在、工艺又好的全铝家具定制商家,那方与圆铝作全铝家居工作…

2026/7/22 4:37:32 阅读更多 →

日新闻

TI DSP系统配置模块SYSCFG详解:中断机制与主设备优先级配置实战

TI DSP系统配置模块SYSCFG详解:中断机制与主设备优先级配置实战

1. 项目概述与SYSCFG模块的核心价值在嵌入式系统,尤其是像TI C6000系列这样的高性能DSP开发中,我们常常会与芯片手册里那些密密麻麻的寄存器打交道。很多开发者可能更关注算法实现、内存优化或者外设驱动,但对于一个稳定、高效的系统而言&…

2026/7/22 0:00:26 阅读更多 →
微信Server酱:高到达率的应急通知方案实践

微信Server酱:高到达率的应急通知方案实践

1. 为什么我们需要"最次"的通知方案? 在数字化协作环境中,消息通知系统的重要性不言而喻明。但现实情况是,企业级通知方案往往需要复杂的API对接(如企业微信、钉钉、飞书),个人开发者的小项目又经…

2026/7/22 0:00:26 阅读更多 →
甲方要的“简洁“PPT,到底是简洁还是省事?

甲方要的“简洁“PPT,到底是简洁还是省事?

甲方说"简洁一点",乙方听到的是"少做几页"。甲方说"不要太复杂",乙方理解成"别放图表了"。结果交过去,甲方说"我说的简洁不是这个意思"。"简洁"这个词在PPT语境里,是…

2026/7/22 0:00:26 阅读更多 →

周新闻

Go语言静态资源打包方案对比与实践指南

Go语言静态资源打包方案对比与实践指南

1. 项目背景与核心需求在Go语言开发中,我们经常需要处理静态资源文件的打包问题。无论是Web应用的模板文件、前端资源,还是配置文件、证书等,都需要随程序一起分发。传统做法是将这些文件与编译后的二进制文件放在同一目录下,但这…

2026/7/21 8:48:31 阅读更多 →
Go语言实现高性能LDAP认证服务的架构与实践

Go语言实现高性能LDAP认证服务的架构与实践

1. 项目背景与核心价值LDAP(轻量级目录访问协议)作为企业级身份认证的黄金标准,已经服务了超过80%的财富500强公司。我在金融科技领域实施统一认证体系时,发现传统Java方案存在启动慢、内存占用高等痛点。而Go语言凭借其协程并发模…

2026/7/21 5:34:47 阅读更多 →
【AI面试官实战指南】:用ChatGPT模拟10类高频技术岗面试,3天提升应答精准度92%

【AI面试官实战指南】:用ChatGPT模拟10类高频技术岗面试,3天提升应答精准度92%

更多请点击: https://intelliparadigm.com 第一章:AI面试官实战指南的核心价值与适用场景 AI面试官并非替代人类HR的“黑箱工具”,而是以可解释、可审计、可迭代的方式,赋能招聘全链路的关键基础设施。其核心价值在于将主观经验沉…

2026/7/21 8:25:39 阅读更多 →

月新闻