如何在应用顶层提供含final字段的ProductModel类(Provider)
使用Provider在应用顶层提供ProductModel并实现状态同步更新
1. 添加Provider依赖
在项目的pubspec.yaml文件的dependencies中添加Provider包:
dependencies: flutter: sdk: flutter provider: ^6.1.1 # 可替换为最新版本
执行flutter pub get完成依赖安装。
2. 在应用顶层提供ProductModel实例
修改main.dart,用ChangeNotifierProvider包裹MaterialApp,让整个应用的所有页面共享同一个ProductModel实例:
import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; import 'your_product_model_path.dart'; // 替换为你的ProductModel文件路径 void main() { runApp( ChangeNotifierProvider( create: (context) => ProductModel( id: 'prod_001', imageUrl: 'https://example.com/product.jpg', name: '示例产品', price: 29.99, ), child: const MyApp(), ), ); } class MyApp extends StatelessWidget { const MyApp({super.key}); @override Widget build(BuildContext context) { return MaterialApp( title: 'Product Demo', home: const HomePage(), routes: { '/detail': (context) => const ProductDetailPage(), }, ); } }
3. 在页面中监听并同步状态
你可以通过两种方式获取并监听ProductModel的状态变化:
方式一:使用Provider.of
直接获取实例并自动监听状态,状态变化时整个widget会重建:
class HomePage extends StatelessWidget { const HomePage({super.key}); @override Widget build(BuildContext context) { final productModel = Provider.of<ProductModel>(context); return Scaffold( appBar: AppBar(title: const Text('首页')), body: Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Text('产品名称:${productModel.name}'), Text('收藏状态:${productModel.isFavorite ? '已收藏' : '未收藏'}'), ElevatedButton( onPressed: () => Navigator.pushNamed(context, '/detail'), child: const Text('查看详情'), ), ], ), ), ); } }
方式二:使用Consumer(更高效)
仅重建需要更新的部分,避免整个页面不必要的重建:
class ProductDetailPage extends StatelessWidget { const ProductDetailPage({super.key}); @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: const Text('产品详情')), body: Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Consumer<ProductModel>( builder: (context, product, child) { return IconButton( icon: Icon( product.isFavorite ? Icons.favorite : Icons.favorite_border, color: Colors.red, size: 40, ), onPressed: () { // 修改收藏状态,触发全局更新 product.isFavorite = !product.isFavorite; }, ); }, ), const SizedBox(height: 20), const Text('点击图标切换收藏状态'), ], ), ), ); } }
核心原理
ChangeNotifierProvider在应用顶层创建ProductModel的单实例,所有子页面通过context获取的都是同一个实例。- 当调用
product.isFavorite = !product.isFavorite时,setter中的notifyListeners()会通知所有监听该实例的组件(Provider.of或Consumer)触发重建,从而实现所有页面的状态同步。
扩展:管理多个产品的情况
如果需要管理多个产品的收藏状态,建议封装一个ProductListModel来维护产品列表,同样混入ChangeNotifier:
class ProductListModel with ChangeNotifier { final List<ProductModel> _products = [ ProductModel(id: '1', name: '产品A', imageUrl: 'xxx', price: 19.99), ProductModel(id: '2', name: '产品B', imageUrl: 'xxx', price: 29.99), ]; List<ProductModel> get products => _products; void toggleFavorite(String productId) { final targetProduct = _products.firstWhere((p) => p.id == productId); targetProduct.isFavorite = !targetProduct.isFavorite; notifyListeners(); } }
之后在顶层提供ProductListModel即可实现多产品的状态同步。
内容的提问来源于stack exchange,提问作者Sapinder Singh
相关产品推荐
相关产品推荐

