鸿蒙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/23 12:43:39 阅读更多 →
2026年语音模块哪里买:核心供应商筛选与高可靠性采购渠道深度解析

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

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

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

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

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

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

最新新闻

看看自己是什么段位?C语言“void”关键字从青铜到大师段位的使用方式汇总!

看看自己是什么段位?C语言“void”关键字从青铜到大师段位的使用方式汇总!

前言 文章摘要 : 在C语言中, void 关键字常被理解为简单的“空”或“无”。本文深入剖析 void 作为“无类型”的 底层逻辑与在架构设计上的应用价值 。文章首先阐述 void 在函数接口设计中作为显式边界限定符的严谨性并辨析新旧C标准的差异;…

2026/7/26 0:38:46 阅读更多 →
【硬核C语言】do…while必执行一次!4个实战妙用新手很少知

【硬核C语言】do…while必执行一次!4个实战妙用新手很少知

很多新手只记住一句话: do…while 不管条件真假,先执行1次循环体,再判断条件 但90%的人只背语法,完全不知道这个特性在实战里到底用来干嘛。 今天不讲废话,只讲单机开发、底层程序、C语言实战中真正能用的妙用&#xf…

2026/7/26 0:38:46 阅读更多 →
Django毕设项目:基于 Django 的多功能网上购物电商服务系统设计 个人用户线上购物消费管理系统 (源码+文档,讲解、调试运行,定制等)

Django毕设项目:基于 Django 的多功能网上购物电商服务系统设计 个人用户线上购物消费管理系统 (源码+文档,讲解、调试运行,定制等)

博主介绍:✌️码农一枚 ,专注于大学生项目实战开发、讲解和毕业🚢文撰写修改等。全栈领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围:&am…

2026/7/26 0:38:46 阅读更多 →
Django毕设项目:基于Django的智慧文旅公园资源定位服务平台实现 城市休闲公园信息归档与定位查询系统 (源码+文档,讲解、调试运行,定制等)

Django毕设项目:基于Django的智慧文旅公园资源定位服务平台实现 城市休闲公园信息归档与定位查询系统 (源码+文档,讲解、调试运行,定制等)

博主介绍:✌️码农一枚 ,专注于大学生项目实战开发、讲解和毕业🚢文撰写修改等。全栈领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围:&am…

2026/7/26 0:38:46 阅读更多 →
容器网络延时与乱序包:veth 的开销到底有多大?

容器网络延时与乱序包:veth 的开销到底有多大?

容器网络延时与乱序包:veth 的开销到底有多大?实验环境:Ubuntu 24.04 / 内核 6.8.0-106-generic / Cgroup v2 / Docker 29.1.3 / 华为云 FlexusX 8C16G(8vCPU/16G)。 全程只操作 docker0 / veth / 自建 netns&#xff…

2026/7/26 0:38:46 阅读更多 →
AI证书的含金量,最终要落到这三个结果上

AI证书的含金量,最终要落到这三个结果上

当下AI考证热潮持续升温,大量求职者、在校学生希望依靠AI证书提升求职竞争力。各类宣传中“高含金量”“入行必备”等标签层出不穷,评判标准却十分模糊。抛开营销概念,一份AI技能证书真正的含金量,最终只需要验证三个核心结果&…

2026/7/26 0:37:46 阅读更多 →

日新闻

深度学习道路桥梁裂缝检测系统 道路桥梁裂缝检测数据集 道路桥梁病害识别检测数据集

深度学习道路桥梁裂缝检测系统 道路桥梁裂缝检测数据集 道路桥梁病害识别检测数据集

深度学习道路桥梁裂缝检测系统 数据集6000张 完整源码已标注数据集训练好的模型环境配置教程程序运行说明文档,可以直接使用!系统支持图片、视频、摄像头等多种方式检测裂缝,功能强大实用。 1数据集6000张 8各类别

2026/7/26 0:00:31 阅读更多 →
深度学习YOLO模型如何训练 PUBG 绝地求生目标检测数据集

深度学习YOLO模型如何训练 PUBG 绝地求生目标检测数据集

pubg数据集 精选原图1.42万数据 1.49万标签 无任何重复、算法增强或冗余图像! pubg绝地求生目标检测数据集 1分类:e_body,14905个标签,txt格式 共计14244张图,99%为640*640尺寸图像 适合yolo目标检测、AI训练关键词&am…

2026/7/26 0:00:31 阅读更多 →
Apex英雄目标检测数据集 深度学习框架YOLO如何训练APEX数据集

Apex英雄目标检测数据集 深度学习框架YOLO如何训练APEX数据集

Apex检测数据集数据集详情检测类别: allies enemy tag图片总量:7247张训练集:5139张验证集:1425张测试集:683张标注状态:全部已标注,即拿即用数据格式:支持YOLO格式及其他格式&#…

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

周新闻

深度学习道路桥梁裂缝检测系统 道路桥梁裂缝检测数据集 道路桥梁病害识别检测数据集

深度学习道路桥梁裂缝检测系统 道路桥梁裂缝检测数据集 道路桥梁病害识别检测数据集

深度学习道路桥梁裂缝检测系统 数据集6000张 完整源码已标注数据集训练好的模型环境配置教程程序运行说明文档,可以直接使用!系统支持图片、视频、摄像头等多种方式检测裂缝,功能强大实用。 1数据集6000张 8各类别

2026/7/26 0:00:31 阅读更多 →
深度学习YOLO模型如何训练 PUBG 绝地求生目标检测数据集

深度学习YOLO模型如何训练 PUBG 绝地求生目标检测数据集

pubg数据集 精选原图1.42万数据 1.49万标签 无任何重复、算法增强或冗余图像! pubg绝地求生目标检测数据集 1分类:e_body,14905个标签,txt格式 共计14244张图,99%为640*640尺寸图像 适合yolo目标检测、AI训练关键词&am…

2026/7/26 0:00:31 阅读更多 →
Apex英雄目标检测数据集 深度学习框架YOLO如何训练APEX数据集

Apex英雄目标检测数据集 深度学习框架YOLO如何训练APEX数据集

Apex检测数据集数据集详情检测类别: allies enemy tag图片总量:7247张训练集:5139张验证集:1425张测试集:683张标注状态:全部已标注,即拿即用数据格式:支持YOLO格式及其他格式&#…

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

月新闻