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

如何使用Provider重构Flutter餐食购物车应用代码?

用Provider重构Flutter餐食应用购物车逻辑

1. 安装Provider依赖

在项目的pubspec.yaml文件中添加Provider包:

dependencies:
  flutter:
    sdk: flutter
  provider: ^6.0.5 # 可替换为最新版本

执行flutter pub get完成依赖安装。

2. 创建购物车状态管理类

新建CartProvider类,继承ChangeNotifier来管理购物车状态,封装添加、删除、清空、计算总价等核心逻辑:

import 'package:flutter/material.dart';
import '../models/meal.dart'; // 替换为你项目中的餐品模型类

class CartProvider extends ChangeNotifier {
  final List<Meal> _cartItems = [];

  // 返回购物车副本,避免外部直接修改源数据
  List<Meal> get cartItems => [..._cartItems];

  // 添加餐品到购物车
  void addItem(Meal meal) {
    _cartItems.add(meal);
    notifyListeners(); // 通知所有监听者状态更新
  }

  // 从购物车删除指定餐品
  void removeItem(Meal meal) {
    _cartItems.remove(meal);
    notifyListeners();
  }

  // 清空购物车
  void clearCart() {
    _cartItems.clear();
    notifyListeners();
  }

  // 计算购物车总价
  double get totalPrice {
    return _cartItems.fold(0.0, (sum, meal) => sum + meal.price);
  }
}

3. 在应用根节点注入Provider

修改main.dart,用ChangeNotifierProvider包裹根Widget,让整个应用都能访问购物车状态:

import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'providers/cart_provider.dart';
import 'screens/categories_screen.dart'; // 你的分类页面

void main() {
  runApp(
    ChangeNotifierProvider(
      create: (context) => CartProvider(),
      child: const MyApp(),
    ),
  );
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: '餐食应用',
      home: const CategoriesScreen(),
    );
  }
}

4. 修改餐品页面的购物车操作逻辑

在餐品列表/详情页,将原来的购物车操作替换为调用CartProvider的方法:

// 餐品列表项的加入购物车按钮
ElevatedButton(
  onPressed: () {
    // listen: false 表示只修改状态,不监听变化
    Provider.of<CartProvider>(context, listen: false).addItem(currentMeal);
    ScaffoldMessenger.of(context).showSnackBar(
      SnackBar(content: Text('${currentMeal.name}已加入购物车')),
    );
  },
  child: const Text('加入购物车'),
)

5. 重构购物车页面,实时监听状态变化

购物车页面需要实时同步购物车内容,通过Provider.of或Consumer监听状态变化:

import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import '../providers/cart_provider.dart';
import '../models/meal.dart';

class CartScreen extends StatelessWidget {
  const CartScreen({super.key});

  @override
  Widget build(BuildContext context) {
    final cartProvider = Provider.of<CartProvider>(context);
    final cartItems = cartProvider.cartItems;

    return Scaffold(
      appBar: AppBar(title: const Text('购物车')),
      body: cartItems.isEmpty
          ? const Center(child: Text('购物车是空的'))
          : Column(
              children: [
                Expanded(
                  child: ListView.builder(
                    itemCount: cartItems.length,
                    itemBuilder: (ctx, index) {
                      final meal = cartItems[index];
                      return ListTile(
                        title: Text(meal.name),
                        subtitle: Text('¥${meal.price.toStringAsFixed(2)}'),
                        trailing: IconButton(
                          icon: const Icon(Icons.delete),
                          onPressed: () {
                            Provider.of<CartProvider>(context, listen: false).removeItem(meal);
                          },
                        ),
                      );
                    },
                  ),
                ),
                Padding(
                  padding: const EdgeInsets.all(16.0),
                  child: Row(
                    mainAxisAlignment: MainAxisAlignment.spaceBetween,
                    children: [
                      const Text(
                        '总价:',
                        style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold),
                      ),
                      // 用Consumer包裹仅需更新的部件,避免整页重建
                      Consumer<CartProvider>(
                        builder: (ctx, provider, child) {
                          return Text(
                            '¥${provider.totalPrice.toStringAsFixed(2)}',
                            style: const TextStyle(fontSize: 18, color: Colors.red),
                          );
                        },
                      ),
                    ],
                  ),
                ),
                ElevatedButton(
                  onPressed: cartItems.isEmpty
                      ? null
                      : () {
                          // 执行结算逻辑
                          Provider.of<CartProvider>(context, listen: false).clearCart();
                          ScaffoldMessenger.of(context).showSnackBar(
                            const SnackBar(content: Text('结算成功')),
                          );
                        },
                  child: const Text('结算'),
                ),
              ],
            ),
    );
  }
}

内容的提问来源于stack exchange,提问作者Sena

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 16:43:08