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

Flutter中点击SnackBar操作按钮刷新更新待处理发票Widget

待处理发票列表Widget的刷新需求实现

我开发了一个展示待处理发票列表的PendingInvoiceWidget,用户点击Accept按钮后会弹出SnackBar。现在需要实现的功能是:点击SnackBar的操作按钮返回该Widget时,自动刷新待处理发票列表,移除已接受的发票。

以下是我的实现代码:

class PendingInvoiceWidget extends StatelessWidget {
  final double maxWidth;
  final double maxHeight;
  final bool isOverdue;
  final String amount;
  final String savedAmount;
  final String invoiceDate;
  final String dueDate;
  Invoice fullDetails;
  int index;
  bool userConsentGiven = false;

  final String companyName;
  PendingInvoiceWidget(
      {required this.fullDetails,
      required this.maxWidth,
      required this.maxHeight,
      required this.amount,
      required this.savedAmount,
      required this.index,
      required this.invoiceDate,
      required this.dueDate,
      required this.companyName,
      required this.isOverdue});

  @override
  Widget build(BuildContext context) {
    TextEditingController acceptController = TextEditingController();
    TextEditingController rejectController = TextEditingController();
    List<Invoice> pendingInvoice =
        Provider.of<TransactionManager>(context).pendingInvoice;
    String? invoiceId = fullDetails.sId;
    String invAmt = double.parse(amount).toStringAsFixed(2);

    DateTime id = DateTime.parse(invoiceDate);
    DateTime dd = DateTime.parse(dueDate);
    DateTime currentDate = DateTime.now();
    Duration dif = dd.difference(currentDate);
    int daysLeft = dif.inDays;
    String idueDate = DateFormat("dd-MMM-yyyy").format(dd);
    String invDate = DateFormat("dd-MMM-yyyy").format(id);

    double h1p = maxHeight * 0.01;
    double h10p = maxHeight * 0.1;
    double w10p = maxWidth * 0.1;
    return ProgressHUD(child: Builder(builder: (context) {
      final progress = ProgressHUD.of(context);
      return ExpandableNotifier(
        child: Padding(
          padding: EdgeInsets.symmetric(horizontal: w10p * .5, vertical: 10),
          child: Expandable(
              collapsed: ExpandableButton(
                child: Card(
                  child: Container(
                    padding: EdgeInsets.all(10),
                    decoration: BoxDecoration(
                      borderRadius: BorderRadius.circular(10),
                      color: Colours.offWhite,
                    ),
                    child: Row(
                        mainAxisAlignment: MainAxisAlignment.spaceBetween,
                        children: [
                          Column(
                            crossAxisAlignment: CrossAxisAlignment.start,
                            children: [
                              isOverdue
                                  ? Padding(
                                      padding: EdgeInsets.symmetric(
                                          vertical: h1p * 1),
                                      child: Container(
                                        decoration: BoxDecoration(
                                          borderRadius:
                                              BorderRadius.circular(5),
                                          color: Colours.failPrimary,
                                        ),
                                        child: const Center(
                                          child: Padding(
                                            padding: EdgeInsets.all(4),
                                            child: Text(
                                              "Overdue",
                                              style: TextStyles.overdue,
                                            ),
                                          ),
                                        ),
                                      ),
                                    )
                                  : Container(),

                              Row(
                                children: [
                                  Text(
                                    "${fullDetails.invoiceNumber}",
                                    style: TextStyles.textStyle6,
                                  ),
                                  SvgPicture.asset(
                                      "assets/images/home_images/arrow-circle-right.svg"),
                                ],
                              ),
                            ]),
                          Column(
                            crossAxisAlignment: CrossAxisAlignment.end,
                            children: [
                              isOverdue
                                  ? Text(
                                      "$daysLeft days Overdue",
                                      style: TextStyles.textStyle57,
                                    )
                                  : Text(
                                      "$daysLeft days left",
                                      style: TextStyles.textStyle57,
                                    ),
                              Text(
                                "₹ $invAmt",
                                style: TextStyles.textStyle58,
                              ),
                            ],
                          )
                        ]),
                  ),
                ),
              ),
              expanded: Column(
                children: [
                  ExpandableButton(
                    child: Card(
                      child: Container(
                        padding: EdgeInsets.all(10),
                        decoration: BoxDecoration(
                          borderRadius: BorderRadius.circular(10),
                          color: Colours.offWhite,
                        ),
                        child: Row(
                            mainAxisAlignment: MainAxisAlignment.spaceBetween,
                            children: [
                              Column(
                                crossAxisAlignment: CrossAxisAlignment.start,
                                children: [
                                  isOverdue
                                      ? Padding(
                                          padding: EdgeInsets.symmetric(
                                              vertical: h1p * 1),
                                          child: Container(
                                            decoration: BoxDecoration(
                                              borderRadius:
                                                  BorderRadius.circular(5),
                                              color: Colours.failPrimary,
                                            ),
                                            child: const Center(
                                              child: Padding(
                                                padding: EdgeInsets.all(4),
                                                child: Text(
                                                  "Overdue",
                                                  style: TextStyles.overdue,
                                                ),
                                              ),
                                            ),
                                          ),
                                        )
                                      : Container(),
                                  Row(
                                    children: [
                                      Text(
                                        "${fullDetails.invoiceNumber}",
                                        style: TextStyles.textStyle6,
                                      ),
                                      SvgPicture.asset(
                                          "assets/images/home_images/arrow-circle-right.svg"),
                                    ],
                                  ),
                                ],
                              ),
                              Column(
                                crossAxisAlignment: CrossAxisAlignment.end,
                                children: [
                                  isOverdue
                                      ? Text(
                                          "$daysLeft days Overdue",
                                          style: TextStyles.textStyle57,
                                        )
                                      : Text(
                                          "$daysLeft days left",
                                          style: TextStyles.textStyle57,
                                        ),
                                  Text(
                                    "₹ $invAmt",
                                    style: TextStyles.textStyle58,
                                  ),
                                ],
                              )
                            ]),
                      ),
                    ),
                  ),
                  Card(
                    elevation: .5,
                    child: Padding(
                      padding: const EdgeInsets.all(10.0),
                      child: Row(
                        mainAxisAlignment: MainAxisAlignment.spaceBetween,
                        children: [
                          Column(
                            crossAxisAlignment: CrossAxisAlignment.start,
                            children: [
                              const SizedBox(
                                height: 4,
                              ),
                              const Text(
                                "Invoice Date",
                                style: TextStyles.textStyle62,
                              ),
                              Text(
                                invDate,
                                style: TextStyles.textStyle63,
                              ),
                            ],
                          ),
                          SvgPicture.asset("assets/images/arrow.svg"),
                          Column(
                            crossAxisAlignment: CrossAxisAlignment.end,
                            children: [
                              const SizedBox(
                                height: 4,
                              ),
                              const Text(
                                "Due Date",
                                style: TextStyles.textStyle62,
                              ),
                              Text(
                                idueDate,
                                style: TextStyles.textStyle63,
                              ),
                            ],
                          ),
                        ],
                      ),
                    ),
                  ),
                  Card(
                    child: Container(
                      padding: const EdgeInsets.all(10),
                      decoration: const BoxDecoration(),
                      child: Column(
                        children: [
                          Row(
                            mainAxisAlignment: MainAxisAlignment.spaceBetween,
                            children: [
                              Column(
                                crossAxisAlignment: CrossAxisAlignment.start,
                                children: [
                                  const SizedBox(
                                    height: 4,
                                  ),
                                  const Text(
                                    "Invoice Amount",
                                    style: TextStyles.textStyle62,
                                  ),
                                  Text(
                                    "₹ $invAmt",
                                    style: TextStyles.textStyle65,
                                  )
                                ],
                              ),
                              Column(
                                crossAxisAlignment: CrossAxisAlignment.end,
                                children: [
                                  const SizedBox(
                                    height: 4,
                                  ),
                                  isOverdue
                                      ? const Text(
                                          "Payabe Amount",
                                          style: TextStyles.textStyle62,
                                        )
                                      : const Text(
                                          "Pay Now",
                                          style: TextStyles.textStyle62,
                                        ),
                                  Text(
                                    "₹ $invAmt",
                                    style: TextStyles.textStyle66,
                                  ),
                                ],
                              ),
                            ],
                          ),
                          SizedBox(
                            height: h1p * 1.5,
                          ),
                          Padding(
                            padding: const EdgeInsets.symmetric(vertical: 10.0),
                            child: GestureDetector(
                                onTap: () {
                                  progress!.show();
                                  getIt<TransactionManager>()
                                      .changeSelectedInvoice(fullDetails);
                                  progress.dismiss();
                                  Navigator.pushNamed(context, savemoreDetails);
                                },
                                child: Image.asset(
                                    "assets/images/viewetails.png")),
                          ),
                          Row(
                            children: [
                              Expanded(
                                child: InkWell(
                                  onTap: () async {
                                    showDialog(
                                        context: context,
                                        builder: (context) => Padding(
                                              padding:
                                                  const EdgeInsets.symmetric(),
                                              child: AlertDialog(
                                                shape:
                                                    const RoundedRectangleBorder(
                                                        borderRadius:
                                                            BorderRadius.all(
                                                                Radius.circular(
                                                                    10.0))),
                                                title: Row(
                                                  children: const [
                                                    Center(
                                                      child: Text("Comment"),
                                                    ),
                                                  ],
                                                ),
                                              ),
                                            ));
                                  },
                                  child: Container(
                                    height: h1p * 9,
                                    decoration: BoxDecoration(
                                        color: Colours.failPrimary,
                                        borderRadius: BorderRadius.circular(5)),
                                    child: const Center(
                                      child: Text(
                                        "Reject",
                                        style: TextStyles.textStyle46,
                                      ),
                                    ),
                                  ),
                                ),
                              ),
                              const SizedBox(
                                width: 10,
                              ),
                              Expanded(
                                child: InkWell(
                                  onTap: () async {
                                    showDialog(
                                        context: context,
                                        builder: (context) => Padding(
                                              padding:
                                                  const EdgeInsets.symmetric(),
                                              child: StatefulBuilder(
                                                  builder: (context, setState) {
                                                return AlertDialog(
                                                  shape:
                                                      const RoundedRectangleBorder(
                                                          borderRadius:
                                                              BorderRadius.all(
                                                                  Radius.circular(
                                                                      10.0))),
                                                  title: const Center(
                                                    child: Text("Consent"),
                                                  ),
                                                  content: Column(
                                                    mainAxisSize:
                                                        MainAxisSize.min,
                                                    children: [
                                                      Text(
                                                          "I agree and approve Xuriti and NBFC Ditya Finance Private Limited to disburse funds to the seller $companyName for invoice number -${fullDetails.invoiceNumber} on my behalf"),
                                                      TextField(
                                                        controller:
                                                            acceptController,
                                                        decoration:
                                                            const InputDecoration(
                                                                hintText:
                                                                    "Leave a comment *"),
                                                        onChanged: (_) {
                                                          print(acceptController
                                                              .text);
                                                          acceptController
                                                                  .text.isEmpty
                                                              ? Row(
                                                                  children: const [
                                                                    Text(
                                                                      "Please write a reason",
                                                                      style: TextStyle(
                                                                          color:
                                                                              Colors.red),
                                                                    ),
                                                                  ],
                                                                )
                                                              : Container();
                                                        },
                                                      ),
                                                      SizedBox(
                                                        height: h1p * 4,
                                                      ),
                                                      InkWell(
                                                        onTap: () async {
                                                          userConsentGiven =
                                                              true;
                                                          String timeStamp =
                                                              DateTime.now()
                                                                  .toString();
                                                          if (acceptController
                                                              .text
                                                              .isNotEmpty) {
                                                            progress!.show();

                                                            String? message = await getIt<
                                                                    TransactionManager>()
                                                                .changeInvoiceStatus(
                                                                    invoiceId,
                                                                    "Confirmed",
                                                                    index,
                                                                    fullDetails,
                                                                    timeStamp,
                                                                    userConsentGiven,
                                                                    acceptController
                                                                        .text,
                                                                    "This invoice has been confirmed and Xuriti and its financing partner is authorised to disburse funds to the seller as per the invoice generated on my behalf");
                                                            progress.dismiss();
                                                            ScaffoldMessenger
                                                                    .of(context)
                                                                .showSnackBar(
                                                                    SnackBar(
                                                                        behavior:
                                                                            SnackBarBehavior
                                                                                .floating,
                                                                        content:
                                                                            Text(
                                                                          message!,
                                                                          style:
                                                                              const TextStyle(color: Colors.green),
                                                                        )));
                                                          } else {
                                                            Fluttertoast.showToast(
                                                                msg:
                                                                    "Please write a reason",
                                                                textColor:
                                                                    Colors.red);
                                                          }

                                                          Navigator.pop(
                                                            context,
                                                          );
                                                        },
                                                        child: Container(
                                                          height: h1p * 8,
                                                          width: w10p * 7.5,
                                                          decoration: BoxDecoration(
                                                              borderRadius:
                                                                  BorderRadius
                                                                      .circular(
                                                                          6),
                                                              color: Colours
                                                                  .pumpkin),
                                                          child: const Center(
                                                              child: Text(
                                                            "Accept",
                                                            style: TextStyles
                                                                .subHeading,
                                                          )),
                                                        ),
                                                      ),
                                                    ],
                                                  ),
                                                );
                                              }),
                                            ));
                                  },
                                  child: Container(
                                    height: h1p * 9,
                                    decoration: BoxDecoration(
                                        color: Colours.successPrimary,
                                        borderRadius: BorderRadius.circular(5)),
                                    child: const Center(
                                      child: Text(
                                        "Accept",
                                        style: TextStyles.textStyle46,
                                      ),
                                    ),
                                  ),
                                ),
                              ),
                            ],
                          )
                        ],
                      ),
                    ),
                  ),
                ],
              )),
        ),
      );
    }));
  }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 17:40:41