Flutter Provider:简单而强大的状态管理

张开发
2026/4/5 22:53:41 15 分钟阅读

分享文章

Flutter Provider:简单而强大的状态管理
Flutter Provider简单而强大的状态管理告别 setState 的混乱拥抱 Provider 的简洁优雅。一、Provider 的核心价值作为一名追求代码如散文般优雅的 UI 匠人我对状态管理工具有着严格的要求。Provider 不仅解决了 Flutter 中的状态共享问题还带来了简洁的语法、高效的性能和易于测试的架构。它就像是 Flutter 状态管理的瑞士军刀——简单却强大。二、基础用法1. 安装 Providerflutter pub add provider2. 基本结构import package:flutter/material.dart; import package:provider/provider.dart; // 1. 创建数据模型 class CounterModel extends ChangeNotifier { int _count 0; int get count _count; void increment() { _count; notifyListeners(); } void decrement() { _count--; notifyListeners(); } } // 2. 包装应用 void main() { runApp( ChangeNotifierProvider( create: (context) CounterModel(), child: MyApp(), ), ); } // 3. 使用数据 class CounterWidget extends StatelessWidget { override Widget build(BuildContext context) { return ConsumerCounterModel( builder: (context, counter, child) { return Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Text(Count: ${counter.count}), SizedBox(height: 20), Row( mainAxisAlignment: MainAxisAlignment.center, children: [ ElevatedButton( onPressed: counter.decrement, child: Text(-), ), SizedBox(width: 20), ElevatedButton( onPressed: counter.increment, child: Text(), ), ], ), ], ); }, ); } }三、高级用法1. 多 Provider 管理void main() { runApp( MultiProvider( providers: [ ChangeNotifierProvider(create: (context) CounterModel()), ChangeNotifierProvider(create: (context) UserModel()), ChangeNotifierProvider(create: (context) ThemeModel()), ], child: MyApp(), ), ); } // 使用多个 Provider class HomePage extends StatelessWidget { override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text(Home), backgroundColor: context.watchThemeModel().primaryColor, ), body: Column( children: [ Text(Welcome, ${context.watchUserModel().name}), Text(Count: ${context.watchCounterModel().count}), ], ), ); } }2. 嵌套 Providerclass UserModel extends ChangeNotifier { String _name Leopold; String get name _name; void updateName(String newName) { _name newName; notifyListeners(); } } class UserProfile extends StatelessWidget { override Widget build(BuildContext context) { return ChangeNotifierProvider( create: (context) UserModel(), child: UserProfileContent(), ); } } class UserProfileContent extends StatelessWidget { override Widget build(BuildContext context) { return Column( children: [ Text(Name: ${context.watchUserModel().name}), TextField( onChanged: (value) { context.readUserModel().updateName(value); }, ), ], ); } }3. 选择器优化class ExpensiveWidget extends StatelessWidget { override Widget build(BuildContext context) { // 只监听 count 变化避免其他属性变化导致重绘 final count context.selectCounterModel, int((counter) counter.count); return Text(Count: $count); } } // 或者使用 Selector 组件 class OptimizedWidget extends StatelessWidget { override Widget build(BuildContext context) { return SelectorCounterModel, int( selector: (context, counter) counter.count, builder: (context, count, child) { return Text(Count: $count); }, ); } }四、实战案例购物车class CartModel extends ChangeNotifier { final ListCartItem _items []; ListCartItem get items _items; int get itemCount _items.length; double get totalPrice { return _items.fold(0, (sum, item) sum item.price * item.quantity); } void addItem(CartItem item) { final existingItem _items.firstWhere( (i) i.id item.id, orElse: () CartItem(id: , name: , price: 0, quantity: 0), ); if (existingItem.id.isNotEmpty) { existingItem.quantity; } else { _items.add(item); } notifyListeners(); } void removeItem(String id) { _items.removeWhere((item) item.id id); notifyListeners(); } void updateQuantity(String id, int quantity) { final item _items.firstWhere((i) i.id id); item.quantity quantity; notifyListeners(); } } class CartItem { final String id; final String name; final double price; int quantity; CartItem({ required this.id, required this.name, required this.price, required this.quantity, }); } // 使用 class CartScreen extends StatelessWidget { override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: Text(购物车)), body: ConsumerCartModel( builder: (context, cart, child) { if (cart.itemCount 0) { return Center(child: Text(购物车为空)); } return ListView.builder( itemCount: cart.itemCount, itemBuilder: (context, index) { final item cart.items[index]; return ListTile( title: Text(item.name), subtitle: Text(¥${item.price}), trailing: Row( mainAxisSize: MainAxisSize.min, children: [ IconButton( onPressed: () cart.updateQuantity(item.id, item.quantity - 1), icon: Icon(Icons.remove), ), Text(${item.quantity}), IconButton( onPressed: () cart.updateQuantity(item.id, item.quantity 1), icon: Icon(Icons.add), ), ], ), ); }, ); }, ), bottomNavigationBar: ConsumerCartModel( builder: (context, cart, child) { return Container( padding: EdgeInsets.all(16), child: Text( 总计: ¥${cart.totalPrice.toStringAsFixed(2)}, style: TextStyle( fontSize: 18, fontWeight: FontWeight.bold, ), ), ); }, ), ); } }五、性能优化使用 const 构造器减少不必要的重建合理使用 select只监听需要的属性批量更新避免频繁调用 notifyListeners()使用 ChangeNotifierProxyProvider处理依赖关系六、最佳实践单一职责每个 Provider 只管理一个业务域分层管理按功能模块组织 Provider测试友好便于单元测试和 widget 测试代码组织将模型和 UI 分离Provider 让状态管理变得简单优雅就像好的设计一样自然。#flutter #provider #state-management #dart #architecture

更多文章