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

Flutter中使用Cubit实现购物车商品增删及价格显示问题排查

解决Flutter Cubit购物车价格不显示问题

以下是针对购物车价格不显示问题的常见排查点和修复方案:

1. 检查CartModel的价格关联逻辑

确保CartModel正确关联ProductModel的价格字段,并且小计计算无误:

class CartModel {
  final ProductModel product;
  int quantity;

  // 直接通过关联的product获取单价,计算小计
  double get unitPrice => product.price;
  double get subtotal => unitPrice * quantity;

  CartModel({required this.product, this.quantity = 1});
}

2. 修正CartCubit的状态更新逻辑

添加/修改商品时,必须创建新的列表和CartModel实例,确保状态不可变,同时正确携带商品价格:

class CartCubit extends Cubit<CartState> {
  CartCubit() : super(CartInitial());

  void addToCart(ProductModel product) {
    if (state is CartLoaded) {
      final currentItems = (state as CartLoaded).cartItems;
      final existingIndex = currentItems.indexWhere((item) => item.product.id == product.id);
      List<CartModel> updatedItems;

      if (existingIndex != -1) {
        // 已有商品,更新数量
        updatedItems = List.from(currentItems);
        updatedItems[existingIndex] = CartModel(
          product: updatedItems[existingIndex].product,
          quantity: updatedItems[existingIndex].quantity + 1,
        );
      } else {
        // 新商品,传入带价格的ProductModel
        updatedItems = [...currentItems, CartModel(product: product)];
      }
      emit(CartLoaded(cartItems: updatedItems));
    } else {
      emit(CartLoaded(cartItems: [CartModel(product: product)]));
    }
  }

  // 数量减少/删除商品逻辑同理,确保创建新实例
  void decreaseQuantity(ProductModel product) {
    if (state is CartLoaded) {
      final currentItems = (state as CartLoaded).cartItems;
      final existingIndex = currentItems.indexWhere((item) => item.product.id == product.id);
      if (existingIndex != -1) {
        final updatedItems = List.from(currentItems);
        final targetItem = updatedItems[existingIndex];
        if (targetItem.quantity > 1) {
          updatedItems[existingIndex] = CartModel(
            product: targetItem.product,
            quantity: targetItem.quantity - 1,
          );
        } else {
          updatedItems.removeAt(existingIndex);
        }
        emit(CartLoaded(cartItems: updatedItems));
      }
    }
  }
}

3. 确保UI层正确读取价格数据

在BlocBuilder中,正确调用CartModel的单价或小计字段,避免字段引用错误:

BlocBuilder<CartCubit, CartState>(
  builder: (context, state) {
    if (state is CartLoaded) {
      return Column(
        children: [
          Expanded(
            child: ListView.builder(
              itemCount: state.cartItems.length,
              itemBuilder: (ctx, idx) {
                final cartItem = state.cartItems[idx];
                return ListTile(
                  title: Text(cartItem.product.name),
                  subtitle: Text('单价: \$${cartItem.unitPrice.toStringAsFixed(2)}'),
                  trailing: Column(
                    mainAxisAlignment: MainAxisAlignment.center,
                    children: [
                      Text('小计: \$${cartItem.subtotal.toStringAsFixed(2)}'),
                      Row(
                        mainAxisSize: MainAxisSize.min,
                        children: [
                          IconButton(
                            icon: const Icon(Icons.remove),
                            onPressed: () => context.read<CartCubit>().decreaseQuantity(cartItem.product),
                          ),
                          Text(cartItem.quantity.toString()),
                          IconButton(
                            icon: const Icon(Icons.add),
                            onPressed: () => context.read<CartCubit>().addToCart(cartItem.product),
                          ),
                        ],
                      ),
                    ],
                  ),
                );
              },
            ),
          ),
          // 显示总计金额
          Padding(
            padding: const EdgeInsets.all(16.0),
            child: Text(
              '总计: \$${state.cartItems.fold(0.0, (sum, item) => sum + item.subtotal).toStringAsFixed(2)}',
              style: const TextStyle(fontSize: 18, fontWeight: FontWeight.bold),
            ),
          ),
        ],
      );
    }
    return const Center(child: Text('购物车为空'));
  },
)

4. 验证CartState的总计计算(可选)

可以在CartLoaded状态中封装总计计算,简化UI层代码:

class CartLoaded extends CartState {
  final List<CartModel> cartItems;
  double get total => cartItems.fold(0.0, (sum, item) => sum + item.subtotal);

  CartLoaded({required this.cartItems});
}

然后UI中直接用state.total获取总计:

Text('总计: \$${state.total.toStringAsFixed(2)}')

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 12:15:44