繁体   English   中英

Flutter - 所有产品的数量在 OnClick 之后返回相同的值

[英]Flutter - Quantity of all Products returns same value after OnClick

简而言之:

  1. 我有多种产品,您可以在其中增加和减少购物车内的价值(数量),提交后,会根据购物车商品生成收据。

  2. 所以问题是每当我尝试滑动提交时,我添加到购物车的第一个产品的数量被分配给每个产品,比如

• 苹果:1

•芒果:2

• 橙色:6

以上是它应该是什么样的

• 苹果:6

•芒果:6

• 橙色:6

这是我得到的结果,注意:结果是从新到旧

  1. 次要问题是,每当我尝试在文本字段中写入任何值并单击提交时,该值仍然没有更新!

该代码由 2 个文件组成:

  1. 父文件
import 'package:ambica_medico/component/result/productcart.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart';
import 'package:flutter_email_sender/flutter_email_sender.dart';
import 'package:url_launcher/url_launcher.dart';
import 'package:whatsapp_unilink/whatsapp_unilink.dart';
import '../../component/buttons/c_button.dart';
import '../../constant.dart';

final FirebaseAuth auth = FirebaseAuth.instance;

Stream<QuerySnapshot> getData() => FirebaseFirestore.instance
    .collection('Users')
    .doc(auth.currentUser?.uid)
    .collection('Carts')
    .snapshots();

class Cart extends StatefulWidget {
  const Cart({Key? key}) : super(key: key);

  @override
  State<Cart> createState() => _CartState();
}

class _CartState extends State<Cart> {

  String _text = '';

  callback(newAbc) {
      pk = newAbc;
  } //Step 5: Callback ready to be passed to the the Procart.

  String? product;
  String qnty = '';
  String? mail;
  String? name;
  String? address;
  String? dln;
  String? gst;

  late final _getData = getData();

  DateTime now = DateTime.now();

  Map<String, String> pk = {};


  @override
  Widget build(BuildContext context) {
    return StreamBuilder<dynamic>(
        stream: _getData,
        builder: (context, snapshot) {
          final tilesList = <Widget>[];

          if (snapshot.hasData) {
            snapshot.data.docs.forEach((value) {

              qnty = value.data()['SIB'].toString();

              pk = {value.id: qnty}; //Step4: A map which holds every product id and qnty

              final productTile = Procart(
                pname: value.data()['Product'],
                subtitle: value.data()['MRP'],
                keyo: value.id,
                controller: qnty, sib: value.data()['OSIB'], tis: value.data()['TIS'], callback: callback, //Callback passed!
              );

              if (_text.isEmpty) {
                tilesList.add(productTile);
              } else {
                if (value
                    .data()['Product']
                    .toUpperCase()
                    .contains(_text.toUpperCase())) {
                  tilesList.add(productTile);
                }
              }

              // print(pk.values); //Returns 5,1
            });

            return SafeArea(
              child: Scaffold(
                resizeToAvoidBottomInset: false,
                appBar: AppBar(
                  leading: Padding(
                    padding: const EdgeInsets.only(left: 20.0, top: 10),
                    child: IconButton(
                      icon: const Icon(
                        Icons.arrow_back_ios_new_rounded,
                        color: Colors.black,
                        size: 20,
                      ),
                      onPressed: () {
                        Navigator.pop(context);
                      },
                    ),
                  ),
                  backgroundColor: const Color(0xFFf5f3f7),
                  elevation: 0,
                ),
                body: GestureDetector(
                  onTap: () => FocusManager.instance.primaryFocus?.unfocus(),
                  child: Container(
                    decoration: kImageBackground.copyWith(),
                    height: MediaQuery.of(context).size.height,
                    child: Stack(children: [
                      Column(
                        children: [
                          SingleChildScrollView(
                            child: Padding(
                              padding: const EdgeInsets.only(
                                  left: 24.0, right: 24.0, top: 40),
                              child: Column(
                                crossAxisAlignment: CrossAxisAlignment.stretch,
                                mainAxisAlignment: MainAxisAlignment.start,
                                children: [
                                  const Text(
                                    'The Cart',
                                    style: TextStyle(
                                      fontSize: 40,
                                      fontFamily: 'ProductSans',
                                      fontWeight: FontWeight.bold,
                                      color: Colors.black,
                                    ),
                                  ),
                                  Padding(
                                    padding:
                                        const EdgeInsets.only(top: 50, bottom: 50),
                                    child: Container(
                                      decoration: BoxDecoration(
                                        borderRadius: BorderRadius.circular(20),
                                        color: Colors.white,
                                        boxShadow: const [
                                          BoxShadow(
                                            color: Color(0x261B1B1A),
                                            blurRadius: 50.0,
                                            spreadRadius: 0,
                                            offset: Offset(0.0, 30.0),
                                          ),
                                        ],
                                      ),
                                      height: 70,
                                      child: Center(
                                        child: TextField(
                                          onChanged: (value) {
                                            setState(() {
                                              _text = value;
                                            });
                                          },
                                          keyboardType: TextInputType.text,
                                          decoration: kDecorS.copyWith(
                                            hintText: 'Search Products',
                                          ),
                                          style: const TextStyle(
                                            fontFamily: 'ProductSans',
                                            fontSize: 18,
                                            fontWeight: FontWeight.w400,
                                            color: Color(0xff0f1511),
                                          ),
                                        ),
                                      ),
                                    ),
                                  ),
                                ],
                              ),
                            ),
                          ),
                          SizedBox(
                            height: MediaQuery.of(context).size.height * 0.55,
                            child: ListView(
                              shrinkWrap: true,
                              physics: const BouncingScrollPhysics(),
                              children: tilesList,
                            ),
                          ),
                        ],
                      ),
                      Positioned(
                        bottom: 0,
                        child: SingleChildScrollView(
                          physics: const NeverScrollableScrollPhysics(),
                          child: Align(
                            alignment: Alignment.bottomCenter,
                            child: Container(
                              width: MediaQuery.of(context).size.width,
                              decoration: const BoxDecoration(
                                borderRadius: BorderRadius.only(
                                  topLeft: Radius.circular(42.0),
                                  topRight: Radius.circular(42.0),
                                ),
                                color: Colors.white,
                              ),
                              child: Padding(
                                padding: const EdgeInsets.only(top: 20),
                                child: Column(
                                  children: [
                                    const Padding(
                                      padding:
                                          EdgeInsets.only(bottom: 10.0),
                                      child: Center(
                                        child: Text(
                                          'Check and then click below to',
                                          style: TextStyle(
                                            fontSize: 14,
                                            fontFamily: 'ProductSans',
                                            fontWeight: FontWeight.bold,
                                            color: Colors.black,
                                          ),
                                        ),
                                      ),
                                    ),
                                    Cbutton(
                                      text: 'Send Order',
                                      onPressed: () async {
                                        String message = "";

                                        DateTime date = DateTime(
                                            now.year, now.month, now.day);

                                        await FirebaseFirestore.instance
                                            .collection('Users')
                                            .doc(auth.currentUser?.uid)
                                            .get()
                                            .then((value) => {
                                                  name = value.data()!['name'],
                                                  address =
                                                      value.data()!['address'],
                                                  dln = value.data()!['dln'],
                                                  gst = value.data()!['gst'],
                                                });

                                        await snapshot.data.docs
                                            .forEach((value) async {
                                          product = value.data()['Product'];
                                          message += '- $product = ${pk.values} \n';
                                        });

                                        final Email email = Email(
                                          body:
                                              "From:- \n\nName: $name\n\nAddress: $address\n\nDrug License No:- $dln\n\nGST No:- $gst\n\nDate:- $date \n\nDear sir,\nPlease dispatch my following order earliest possible through\n $message \n\nThanks & Regards,\n$name",
                                          subject: 'Order Detail',
                                          recipients: ['calagency03@gmail.com'],
                                          isHTML: false,
                                        );

                                        final link = WhatsAppUnilink(
                                          phoneNumber: '+91 2313210000',
                                          text:
                                          "From:- \n\nName: $name\n\nAddress: $address\n\nDrug License No:- $dln\n\nGST No:- $gst\n\nDate:- $date \n\nDear sir,\nPlease dispatch my following order earliest possible through\n $message \n\nThanks & Regards,\n$name",
                                        );

                                        await FlutterEmailSender.send(email);

                                        final url = Uri.parse('$link');

                                        await launchUrl(url, mode: LaunchMode.externalApplication,);

                                      },
                                      icon: const Icon(
                                        Icons.send_rounded,
                                        color: Colors.black,
                                        size: 20,
                                      ),
                                      color: const Color(0xff0f1511),
                                    ),
                                  ],
                                ),
                              ),
                            ),
                          ),
                        ),
                      )
                    ]),
                  ),
                ),
              ),
            );
          } else {
            return const Center(
              child: CircularProgressIndicator(),
            );
          }
        });
  }
}

打印产品小票的主要逻辑是:

await snapshot.data.docs
                                            .forEach((value) async {
                                          product = value.data()['Product'];
                                          message += '- $product = ${pk.values} \n';
                                        });
  1. 子文件
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart';
import 'package:flutter_slidable/flutter_slidable.dart';


class Procart extends StatefulWidget {
  final String pname;
  final String subtitle;
  final String keyo; // Step1: Product id
  final String sib;
  final String tis;
  final String controller; // Step2:  Initial Value/ Qnty
  final Function(Map) callback; // Step3: Callback to parents widget in which it passes updated qnty

  const Procart(
      {Key? key,
        required this.pname,
        required this.subtitle,
        required this.keyo, required this.controller, required this.sib, required this.tis, required this.callback})
      : super(key: key);

  @override
  State<Procart> createState() => _ProcartState();
}

class _ProcartState extends State<Procart> {

  final FirebaseAuth auth = FirebaseAuth.instance;

  late TextEditingController controller = TextEditingController(text: widget.controller);

  Map<String, String> lk = {};

  sub() {
    setState(() {
      controller.text =
          (int.parse(controller.text) - 1).toString();
    });
  }

  add() {
    setState(() {
      controller.text =
          (int.parse(controller.text) + 1).toString();
    });
  }

  // @override
  // void didUpdateWidget(covariant Procart oldWidget) {
  //   // TODO: implement didUpdateWidget
  //   super.didUpdateWidget(oldWidget);
  //
  //
  // }

  @override
  Widget build(BuildContext context) {
    lk = { widget.keyo : controller.text }; // This map is used to store updated value

    widget.callback(lk); // send updated value back to parent class but the value still remains 2,2,2 instead of 1,7,2

    print(lk.values);

    return GestureDetector(
      onTap: () => FocusManager.instance.primaryFocus?.unfocus(),
      child: Padding(
          padding: const EdgeInsets.only(bottom: 10),
          child: Slidable(
              key: Key(widget.keyo),
              endActionPane: ActionPane(motion: const ScrollMotion(), children: [
                SlidableAction(
                  // An action can be bigger than the others.
                  onPressed: (value) {
                    FirebaseFirestore.instance
                        .collection('Users')
                        .doc(auth.currentUser?.uid)
                        .collection('Carts')
                        .doc(widget.keyo)
                        .delete();
                  },
                  backgroundColor: const Color(0xFFD16464),
                  foregroundColor: Colors.white,
                  icon: Icons.clear_rounded,
                ),
              ]),
              child: Padding(
                padding: const EdgeInsets.only(left: 28.0, right: 28.0),
                child: Container(
                  decoration: BoxDecoration(
                      color: Colors.white,
                      borderRadius: BorderRadius.circular(10)
                  ),
                  child: Padding(
                    padding: const EdgeInsets.all(12.0),
                    child: Row(
                        mainAxisAlignment: MainAxisAlignment.spaceBetween,
                        children: [
                          SizedBox(
                            width: MediaQuery.of(context).size.width * 0.4,
                            child: Column(
                              crossAxisAlignment: CrossAxisAlignment.start,
                              children: [
                                Text(
                                  widget.pname,
                                  style: const TextStyle(
                                    fontFamily: 'Satoshi',
                                    fontSize: 16,
                                    fontWeight: FontWeight.bold,
                                    color: Color(0xff0f1511),
                                  ),
                                ),
                                Text(
                                  '${widget.subtitle} | ${widget.sib} x ${widget.tis}',
                                  style: const TextStyle(
                                    fontFamily: 'Satoshi',
                                    fontSize: 12,
                                    fontWeight: FontWeight.normal,
                                    color: Color(0xff0f1511),
                                  ),
                                ),
                              ],
                            ),
                          ),
                          Row(
                            children: [
                              CircleAvatar(
                                radius: 16,
                                backgroundColor: const Color(0xff1b1b1b),
                                child: IconButton(
                                  iconSize: 13,
                                  icon: const Icon(
                                    Icons.remove,
                                    color: Colors.white,
                                  ),
                                  onPressed: () {
                                      if (int.parse(controller.text) >
                                          int.parse(widget.sib)) {
                                        sub();
                                      }
                                  },
                                ),
                              ),
                              SizedBox(
                                width: 80,
                                child: TextFormField(
                                  textAlign: TextAlign.center,
                                  decoration: const InputDecoration(
                                    border: InputBorder.none,
                                    contentPadding: EdgeInsets.only(left: 6, right: 6),
                                  ),
                                  controller: controller,
                                  onEditingComplete: () {
                                    controller;
                                  },
                                  keyboardType: TextInputType.number,
                                  style: const TextStyle(
                                    fontFamily: 'Satoshi',
                                    fontSize: 16.0,
                                    fontWeight: FontWeight.bold,
                                    color: Color(0xff0f1511),
                                  ),
                                ),
                              ),
                              CircleAvatar(
                                radius: 16,
                                backgroundColor: const Color(0x33bababa),
                                child: IconButton(
                                  iconSize: 13,
                                  icon: const Icon(
                                    Icons.add,
                                    color: Color(0xff1b1b1b),
                                  ),
                                  onPressed: () {
                                    add();
                                  },
                                ),
                              ),
                            ],
                          ),
                        ]),
                  ),
                ),
              ))),
    );
  }
}

有关更多信息,我在下面附上了屏幕截图:

非常感谢任何帮助我解决这个问题的人!

应用内 SS

收据生成时

好吧,我按照以下步骤解决了这个问题:

解决问题的步骤!

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM