You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在应用顶层提供含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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.10 13:15:22