Flutter项目中的自增和自减问题

问题描述 投票:0回答:1

我的代码遇到一些问题。 因此,我尝试创建一个产品购物车,用户单击 + 按钮以增加产品数量,然后单击 - 按钮以减少产品数量。此外,这些产品是推荐产品,因此它们的默认数量应为 1 个产品。但是当我将初始数量设置为 1 时,它的表现并不好。当我单击产品一次时,它不会更新,但是当我第二次单击时,它会将其更新为 2。我尝试执行一些打印语句,我注意到默认值仍然是 0,当单击一次时,它只是更新为 1,第二次现在是 2,现在 UI 上发生了变化。我如何让它知道现有的商品数量为 1,因此当我增加它时,它会立即更改为 2。另外,当我减少它时,它会更改为 0,因为默认情况下它是 1。

这些是我的代码 我正在使用提供程序进行状态管理

//cart_provider.dart

import 'package:flutter/material.dart';
import '../models/product_model.dart';

class CartProvider with ChangeNotifier {
  List<Product> cartItems = [];

  void addProduct(Product product) {
    final existingProductIndex =
        cartItems.indexWhere((p) => p.productName == product.productName);
    if (existingProductIndex != -1) {
      cartItems[existingProductIndex].quantity++;
    } else {
      product.quantity = 0;
      cartItems.add(product);
    }
    notifyListeners();
  }

  void updateQuantity(Product product, bool isIncrement) {
    final existingProductIndex =
        cartItems.indexWhere((p) => p.productId == product.productId);
    if (existingProductIndex != -1) {
      if (isIncrement && product.quantity < 99) {
        cartItems[existingProductIndex].quantity++;
        product.isDecrementButtonDisabled = false;
      } else if (!isIncrement) {
        cartItems[existingProductIndex].quantity--;
        if (cartItems[existingProductIndex].quantity == 0) {
          product.isDecrementButtonDisabled = true;
        }
      }
    } else {
      addProduct(product);
    }
    notifyListeners();
  }
}

//product_card.dart(这是我显示数据的地方”

import 'package:flutter/material.dart';
import 'package:greenbii_app/providers/cart_provider.dart';
import 'package:intl/intl.dart';
import 'package:provider/provider.dart';

import '../constants/constants.dart';
import '../models/product_model.dart';

class ProductCard extends StatelessWidget {
  final Product product;

  const ProductCard({
    Key? key,
    required this.product,
  }) : super(key: key);

  @override
  Widget build(BuildContext context) {
    NumberFormat currencyFormat = NumberFormat.currency(
      locale: 'en_NG',
      name: 'naira',
      symbol: '₦',
    );
    return Consumer<CartProvider>(
      builder: (context, cartProvider, child) {
        return Row(
          mainAxisAlignment: MainAxisAlignment.spaceBetween,
          children: [
            Expanded(
              child: Column(
                crossAxisAlignment: CrossAxisAlignment.start,
                children: [
                  Text(
                    product.productName,
                    overflow: TextOverflow.ellipsis,
                    style: const TextStyle(
                      color: AppColors.textColor,
                      fontSize: 16.0,
                      fontWeight: FontWeight.w700,
                    ),
                  ),
                  Text(
                    product.descriptions,
                    overflow: TextOverflow.ellipsis,
                    style: const TextStyle(
                      color: AppColors.disabledColor,
                      fontSize: 12.0,
                      fontWeight: FontWeight.w500,
                    ),
                  ),
                  const SizedBox(height: 10.0),
                  Text(
                    currencyFormat.format(double.parse(product.amount)),
                    overflow: TextOverflow.ellipsis,
                    style: const TextStyle(
                      color: AppColors.primaryColor,
                      fontSize: 18.0,
                      fontWeight: FontWeight.w600,
                    ),
                  ),
                ],
              ),
            ),
            Row(
              children: [
                IconButton(
                  onPressed: product.isDecrementButtonDisabled
                      ? null
                      : () => context
                          .read<CartProvider>()
                          .updateQuantity(product, false),
                  icon: const Icon(Icons.remove),
                ),
                const SizedBox(width: 10.0),
                Text(product.quantity.toString()),
                const SizedBox(width: 10.0),
                IconButton(
                  onPressed: () => context
                      .read<CartProvider>()
                      .updateQuantity(product, true),
                  icon: const Icon(Icons.add),
                ),
              ],
            )
          ],
        );
      },
    );
  }
}

//product_model.dart

class Product {
  final int productId;
  final String productName;
  final String descriptions;
  final String amount;
  bool isDecrementButtonDisabled = false;
  int quantity = 1;

  Product({
    required this.productId,
    required this.productName,
    required this.descriptions,
    required this.amount,
  });

  @override
  bool operator ==(Object other) =>
      identical(this, other) ||
      other is Product &&
          runtimeType == other.runtimeType &&
          productId == other.productId;

  @override
  int get hashCode => productId.hashCode;
}

//loan_application.dart

import 'package:flutter/material.dart';
import 'package:greenbii_app/constants/constants.dart';
import 'package:greenbii_app/providers/cart_provider.dart';
import 'package:greenbii_app/widgets/menu_app_bar.dart';
import 'package:provider/provider.dart';

import '../models/product_model.dart';
import '../navigations/navigate.dart';
import '../widgets/data/product_data.dart';
import '../widgets/product_card.dart';

class LoanApplication extends StatefulWidget {
  const LoanApplication({super.key});

  @override
  State<LoanApplication> createState() => _LoanApplicationState();
}

class _LoanApplicationState extends State<LoanApplication> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: const MenuAppBar(
        menuName: 'Loan Application',
        isBack: true,
      ),
      body: SingleChildScrollView(
        child: Padding(
          padding: const EdgeInsets.all(16.0),
          child: Column(
            crossAxisAlignment: CrossAxisAlignment.start,
            children: [
              Container(
                width: double.infinity,
                decoration: BoxDecoration(
                  color: AppColors.successColor,
                  borderRadius: BorderRadius.circular(10),
                ),
                child: const Padding(
                  padding: EdgeInsets.all(16.0),
                  child: Text(
                    'Best rate! The Purchasing Power Index of your business has been applied to your interest rate.',
                    style: TextStyle(
                      color: AppColors.primaryColor,
                    ),
                  ),
                ),
              ),
              const SizedBox(height: 50),
              const Text(
                'Recommended Devices',
                style: TextStyle(
                  fontSize: 16,
                  fontWeight: FontWeight.w600,
                ),
              ),
              const SizedBox(height: 10),
              Container(
                width: double.infinity,
                padding: const EdgeInsets.symmetric(
                    vertical: 31.0, horizontal: 21.0),
                decoration: BoxDecoration(
                  color: AppColors.whiteColor,
                  borderRadius: BorderRadius.circular(20.0),
                  boxShadow: const [
                    BoxShadow(
                      color: AppColors.shadowColor,
                      spreadRadius: 0.0,
                      blurRadius: 20.0,
                    ),
                  ],
                ),
                child: ListView.separated(
                  itemCount: products.length,
                  shrinkWrap: true,
                  physics: const NeverScrollableScrollPhysics(),
                  itemBuilder: (context, index) {
                    final product = products[index];
                    // final cart = Provider.of<CartProvider>(context);
                    return Consumer<CartProvider>(
                        builder: (context, cartProvider, child) {
                      return ProductCard(
                        key: ValueKey(product.productId),
                        product: product,
                      );
                    });
                  },
                  separatorBuilder: (context, index) => const Divider(
                    height: 30.0,
                  ),
                ),
              ),
              const SizedBox(height: 20),
              const Text(
                'More Devices',
                style: TextStyle(
                  fontSize: 16,
                  fontWeight: FontWeight.w600,
                ),
              ),
              const SizedBox(height: 10),
              Container(
                width: double.infinity,
                padding: const EdgeInsets.symmetric(
                    vertical: 31.0, horizontal: 21.0),
                decoration: BoxDecoration(
                  color: AppColors.whiteColor,
                  borderRadius: BorderRadius.circular(20.0),
                  boxShadow: const [
                    BoxShadow(
                      color: AppColors.shadowColor,
                      spreadRadius: 0.0,
                      blurRadius: 20.0,
                    ),
                  ],
                ),
                child: ListView.separated(
                  itemCount: products.length,
                  shrinkWrap: true,
                  physics: const NeverScrollableScrollPhysics(),
                  itemBuilder: (context, index) {
                    final product = products[index];
                    final cart = Provider.of<CartProvider>(context);
                    return ProductCard(
                      key: ValueKey(product.productId),
                      product: product,
                    );
                  },
                  separatorBuilder: (context, index) => const Divider(
                    height: 30.0,
                  ),
                ),
              ),
            ],
          ),
        ),
      ),
      floatingActionButtonLocation: FloatingActionButtonLocation.centerFloat,
      floatingActionButton: Padding(
        padding: const EdgeInsets.symmetric(horizontal: 16.0),
        child: GestureDetector(
          onTap: () {
            // navigate(context, const LoanApplication());
          },
          child: Container(
            width: double.infinity,
            padding: const EdgeInsets.all(16),
            decoration: BoxDecoration(
              borderRadius: BorderRadius.circular(20),
              color: AppColors.primaryColor,
            ),
            child: const Text(
              textAlign: TextAlign.center,
              'Apply for Funding',
              style: TextStyle(
                color: Colors.white,
                fontSize: 16,
              ),
            ),
          ),
        ),
      ),
    );
  }
}

//product_data.dart

import 'package:greenbii_app/models/product_model.dart';

final List<Product> products = [
  Product(
    productId: 1,
    productName: 'Mobile Tablet',
    descriptions: '10 inches screen, 4g ram, table or wall fitted.',
    amount: '100000.00',
  ),
  Product(
    productId: 2,
    productName: 'Laptop',
    descriptions: '(500GB HDD, 8GB RAM, Core i5).',
    amount: '250000.00',
  ),
  Product(
    productId: 3,
    productName: '2.5Kva Backup Solar',
    descriptions: '24v hybrid inverter, 2 batteries, 4 380W panels.',
    amount: '300000.00',
  ),
];

如果我能得到快速回复和详细解释,我会很高兴,因为我只是一个初学者颤振开发人员。

谢谢你们。我真的很感激。

flutter dart widget flutter-provider
1个回答
0
投票

问题是,在任何产品的第一次增量时,您实际上还没有在

cartItems
中拥有该产品。直接从
products
列表读取产品,因此第一个增量仅将产品添加到
cartItems
。既然您说这些产品的初始数量应该为 1,这意味着您应该从一开始就使用
cartItems
列表中的产品填充
products
。您可以通过更改
cartItems
的初始化来解决它,如下所示:

class CartProvider with ChangeNotifier {
  List<Product> cartItems = [...products];

  // ...
}
© www.soinside.com 2019 - 2024. All rights reserved.