如何在数据库更新后立即更新我的Flutter UI?

kb5ga3dv  于 2023-03-13  发布在  Flutter
关注(0)|答案(1)|浏览(260)

我有一个表,显示了我的数据库中的一些数据。我在同一屏幕上有一个按钮,用于显示弹出窗口,即一个表单。我使用此表单在数据库中输入新数据。我希望它是这样的,只要我向数据库提交数据,在后台打开的表应更新并显示添加的数据。
我希望当我按下弹出窗体中的添加按钮时,后台的表格应显示添加的数据。

销售记录表:

import 'package:ame/models/sales.dart';
import 'package:ame/screens/Records/sales_entry_form.dart';
import 'package:ame/services/saleServices.dart';
import 'package:flutter/material.dart';
import 'package:intl/intl.dart';

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

  @override
  State<SalesRecords> createState() => _SalesRecordsState();
}

class _SalesRecordsState extends State<SalesRecords> {
  var now = DateTime.now();

  late DateTime _selectedDate = DateTime(now.year, now.month, now.day);
  late int _selectedDateSeconds = _selectedDate.millisecondsSinceEpoch;

  var saleService = SaleServices();
  List<Sale> sales = [];
  List<Sale> filteredSales = [];

  Color receiptedRowColor = Colors.lightGreenAccent;

  int totalSales = 0;

  bool receiptedFiltered = false;

  final searchController = TextEditingController();

  fetchSalesList(BuildContext context) async {
    var response =
        await saleService.fetchSalesByDate(context, _selectedDateSeconds);

    setState(() {
      sales = response;
      totalSales = 0;
      for (var sale in sales) {
        totalSales = totalSales + sale.amount;
      }
    });
  }

  fetchReceiptedSales(BuildContext context) async {
    var response =
        await saleService.fetchReceiptedSales(context, _selectedDateSeconds);

    setState(() {
      sales = response;
      totalSales = 0;
      for (var sale in sales) {
        totalSales = totalSales + sale.amount;
      }
    });
  }

  updatesale(BuildContext context, int id, Map<String, dynamic> info) async {
    await saleService.updateSale(context, id, info);
  }

  Future<void> _selectDate() async {
    final DateTime? d = await showDatePicker(
      context: context,
      initialDate: _selectedDate,
      firstDate: DateTime(2015, 8),
      lastDate: DateTime(2101),
    );
    if (d != null) {
      setState(() {
        _selectedDate = d;
        _selectedDateSeconds = d.millisecondsSinceEpoch;
      });
      fetchSalesList(context);
    }
  }

  toggleReceiptedSales(BuildContext context) async {
    setState(() {
      receiptedFiltered = !receiptedFiltered;
    });
    receiptedFiltered ? fetchReceiptedSales(context) : fetchSalesList(context);
  }

  updateSale(BuildContext context, int id, Map<String, dynamic> info) async {
    await saleService.updateSale(context, id, info);
  }

  void _onSearchTextChanged(String text) {
    setState(() {
      filteredSales = text.isEmpty
          ? []
          : sales
              .where((sale) =>
                  sale.contact.toLowerCase().contains(text.toLowerCase()))
              .toList();
    });
  }

  @override
  void initState() {
    super.initState();
    Future.delayed(Duration.zero, () {
      fetchSalesList(context);
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Container(
        margin: const EdgeInsets.all(20.0),
        height: MediaQuery.of(context).size.height,
        width: MediaQuery.of(context).size.width,
        child: Column(children: [
          SizedBox(
            width: MediaQuery.of(context).size.width,
            child: Row(mainAxisSize: MainAxisSize.min, children: [
              IconButton(
                  onPressed: () {
                    Navigator.of(context).pop();
                  },
                  icon: const Icon(Icons.arrow_back)),
            ]),
          ),
          const Padding(
            padding: EdgeInsets.symmetric(vertical: 10.0),
            child: Text("Sales Records",
                style: TextStyle(fontWeight: FontWeight.bold, fontSize: 20)),
          ),
          Padding(
            padding: const EdgeInsets.all(5.0),
            child: Row(
              mainAxisAlignment: MainAxisAlignment.spaceBetween,
              children: [
                Row(
                  children: <Widget>[
                    InkWell(
                      child:
                          Text(DateFormat.yMMMMd("en_US").format(_selectedDate),
                              textAlign: TextAlign.center,
                              style: const TextStyle(
                                color: Color(0xFF000000),
                                fontSize: 15,
                              )),
                      onTap: () {
                        _selectDate();
                      },
                    ),
                    IconButton(
                      icon: Icon(
                        Icons.calendar_today,
                        color: Theme.of(context).colorScheme.primary,
                      ),
                      tooltip: 'choose date',
                      onPressed: () async {
                        _selectDate();
                      },
                    ),
                  ],
                ),
                Container(
                  width: 300,
                  child: TextField(
                    controller: searchController,
                    decoration: const InputDecoration(
                      hintText: "Search Contact",
                      border: UnderlineInputBorder(
                        borderRadius: BorderRadius.zero,
                      ),
                    ),
                    onChanged: _onSearchTextChanged,
                  ),
                ),
                TextButton(
                    onPressed: () {
                      formPopUp(context);
                    },
                    child: const Text(
                      "Add New Record",
                      style: TextStyle(fontWeight: FontWeight.bold),
                    ))
              ],
            ),
          ),
          Table(
              border: TableBorder(
                  horizontalInside:
                      BorderSide(color: Theme.of(context).colorScheme.primary)),
              children: [
                TableRow(
                    decoration: BoxDecoration(
                        color: Theme.of(context).colorScheme.primary),
                    children: [
                      SizedBox(
                        height: 40,
                        child: Column(
                            mainAxisAlignment: MainAxisAlignment.center,
                            children: const [
                              Text('R_No',
                                  style: TextStyle(
                                      fontWeight: FontWeight.bold,
                                      fontSize: 18.0))
                            ]),
                      ),
                      SizedBox(
                        height: 40,
                        child: Column(
                            mainAxisAlignment: MainAxisAlignment.center,
                            children: const [
                              Text('Contact',
                                  style: TextStyle(
                                      fontWeight: FontWeight.bold,
                                      fontSize: 18.0))
                            ]),
                      ),
                      SizedBox(
                        height: 40,
                        child: Column(
                            mainAxisAlignment: MainAxisAlignment.center,
                            children: const [
                              Text('Description',
                                  style: TextStyle(
                                      fontWeight: FontWeight.bold,
                                      fontSize: 18.0))
                            ]),
                      ),
                      SizedBox(
                        height: 40,
                        child: Column(
                            mainAxisAlignment: MainAxisAlignment.center,
                            children: const [
                              Text('Amount',
                                  style: TextStyle(
                                      fontWeight: FontWeight.bold,
                                      fontSize: 18.0))
                            ]),
                      ),
                      SizedBox(
                        height: 40,
                        child: Column(
                            mainAxisAlignment: MainAxisAlignment.center,
                            children: const [
                              Text('Delivered',
                                  style: TextStyle(
                                      fontWeight: FontWeight.bold,
                                      fontSize: 18.0))
                            ]),
                      ),
                      SizedBox(
                        height: 40,
                        child: Column(
                            mainAxisAlignment: MainAxisAlignment.center,
                            children: [
                              InkWell(
                                onTap: () {
                                  toggleReceiptedSales(context);
                                },
                                child: const Text('Receipted',
                                    style: TextStyle(
                                        fontWeight: FontWeight.bold,
                                        fontSize: 18.0)),
                              )
                            ]),
                      ),
                    ]),
                if (searchController.text.trim() != "")
                  for (int i = 0; i < filteredSales.length; i++)
                    filteredTableRow(context, i)
                else
                  for (int i = 0; i < sales.length; i++)
                    fullTableRow(context, i)
              ]),
          Row(
            mainAxisAlignment: MainAxisAlignment.end,
            children: [
              Text("Total: KES. ${NumberFormat('#,###.##').format(totalSales)}",
                  style: const TextStyle(
                      fontWeight: FontWeight.bold, fontSize: 15))
            ],
          )
        ]),
      ),
    );
  }

  formPopUp(BuildContext context) {
    return showDialog(
      context: context,
      builder: (BuildContext context) {
        return AlertDialog(
          title: const Text(
            "Enter New Sale Record",
            style: TextStyle(fontWeight: FontWeight.bold),
          ),
          content: SalesEntryForm(date: _selectedDateSeconds),
        );
      },
    );
  }

  TableRow fullTableRow(BuildContext context, int i) {
    return TableRow(
        decoration: BoxDecoration(
          color: sales[i].receipted
              ? receiptedRowColor
              : (i) % 2 == 0
                  ? const Color.fromRGBO(7, 96, 49, 0)
                  : const Color.fromARGB(100, 7, 96, 49),
        ),
        children: [
          TableCell(
            verticalAlignment: TableCellVerticalAlignment.middle,
            child: EditableText(
              controller: TextEditingController(text: sales[i].rNo),
              style: const TextStyle(fontSize: 15.0, color: Colors.black),
              backgroundCursorColor: Theme.of(context).colorScheme.primary,
              cursorColor: Theme.of(context).colorScheme.primary,
              focusNode: FocusNode(),
              textAlign: TextAlign.center,
              onSubmitted: (value) {
                updateSale(context, sales[i].id, {"R_No": value});
              },
            ),
          ),
          TableCell(
            verticalAlignment: TableCellVerticalAlignment.middle,
            child: EditableText(
              controller: TextEditingController(text: sales[i].contact),
              style: const TextStyle(fontSize: 15.0, color: Colors.black),
              backgroundCursorColor: Theme.of(context).colorScheme.primary,
              cursorColor: Theme.of(context).colorScheme.primary,
              focusNode: FocusNode(),
              textAlign: TextAlign.center,
              onSubmitted: (value) {
                updateSale(context, sales[i].id, {"contact": value});
              },
            ),
          ),
          TableCell(
            verticalAlignment: TableCellVerticalAlignment.middle,
            child: EditableText(
              controller: TextEditingController(text: sales[i].description),
              style: const TextStyle(fontSize: 15.0, color: Colors.black),
              backgroundCursorColor: Theme.of(context).colorScheme.primary,
              cursorColor: Theme.of(context).colorScheme.primary,
              focusNode: FocusNode(),
              textAlign: TextAlign.center,
              onSubmitted: (value) {
                updateSale(context, sales[i].id, {"description": value});
              },
            ),
          ),
          TableCell(
            verticalAlignment: TableCellVerticalAlignment.middle,
            child: EditableText(
              controller:
                  TextEditingController(text: sales[i].amount.toString()),
              style: const TextStyle(fontSize: 15.0, color: Colors.black),
              backgroundCursorColor: Theme.of(context).colorScheme.primary,
              cursorColor: Theme.of(context).colorScheme.primary,
              focusNode: FocusNode(),
              textAlign: TextAlign.center,
              onSubmitted: (value) {
                updateSale(context, sales[i].id, {"amount": int.parse(value)});
              },
            ),
          ),
          TableCell(
            verticalAlignment: TableCellVerticalAlignment.middle,
            child: Checkbox(
              value: sales[i].delivered,
              onChanged: ((newValue) {
                setState(() {
                  sales[i].delivered = newValue!;
                });
                updateSale(context, sales[i].id, {"delivered": newValue!});
              }),
              activeColor: Theme.of(context).colorScheme.primary,
            ),
          ),
          TableCell(
            verticalAlignment: TableCellVerticalAlignment.middle,
            child: Checkbox(
              value: sales[i].receipted,
              onChanged: ((newValue) {
                setState(() {
                  sales[i].receipted = newValue!;
                });
                updateSale(context, sales[i].id, {"receipted": newValue!});
              }),
              activeColor: Theme.of(context).colorScheme.primary,
            ),
          ),
        ]);
  }

  TableRow filteredTableRow(BuildContext context, int i) {
    return TableRow(
        decoration: BoxDecoration(
          color: filteredSales[i].receipted
              ? receiptedRowColor
              : (i) % 2 == 0
                  ? const Color.fromRGBO(7, 96, 49, 0)
                  : const Color.fromARGB(100, 7, 96, 49),
        ),
        children: [
          TableCell(
            verticalAlignment: TableCellVerticalAlignment.middle,
            child: EditableText(
              controller: TextEditingController(text: filteredSales[i].rNo),
              style: const TextStyle(fontSize: 15.0, color: Colors.black),
              backgroundCursorColor: Theme.of(context).colorScheme.primary,
              cursorColor: Theme.of(context).colorScheme.primary,
              focusNode: FocusNode(),
              textAlign: TextAlign.center,
              onSubmitted: (value) {
                updateSale(context, filteredSales[i].id, {"R_No": value});
              },
            ),
          ),
          TableCell(
            verticalAlignment: TableCellVerticalAlignment.middle,
            child: EditableText(
              controller: TextEditingController(text: filteredSales[i].contact),
              style: const TextStyle(fontSize: 15.0, color: Colors.black),
              backgroundCursorColor: Theme.of(context).colorScheme.primary,
              cursorColor: Theme.of(context).colorScheme.primary,
              focusNode: FocusNode(),
              textAlign: TextAlign.center,
              onSubmitted: (value) {
                updateSale(context, filteredSales[i].id, {"contact": value});
              },
            ),
          ),
          TableCell(
            verticalAlignment: TableCellVerticalAlignment.middle,
            child: EditableText(
              controller:
                  TextEditingController(text: filteredSales[i].description),
              style: const TextStyle(fontSize: 15.0, color: Colors.black),
              backgroundCursorColor: Theme.of(context).colorScheme.primary,
              cursorColor: Theme.of(context).colorScheme.primary,
              focusNode: FocusNode(),
              textAlign: TextAlign.center,
              onSubmitted: (value) {
                updateSale(
                    context, filteredSales[i].id, {"description": value});
              },
            ),
          ),
          TableCell(
            verticalAlignment: TableCellVerticalAlignment.middle,
            child: EditableText(
              controller: TextEditingController(
                  text: filteredSales[i].amount.toString()),
              style: const TextStyle(fontSize: 15.0, color: Colors.black),
              backgroundCursorColor: Theme.of(context).colorScheme.primary,
              cursorColor: Theme.of(context).colorScheme.primary,
              focusNode: FocusNode(),
              textAlign: TextAlign.center,
              onSubmitted: (value) {
                updateSale(
                    context, filteredSales[i].id, {"amount": int.parse(value)});
              },
            ),
          ),
          TableCell(
            verticalAlignment: TableCellVerticalAlignment.middle,
            child: Checkbox(
              value: filteredSales[i].delivered,
              onChanged: ((newValue) {
                setState(() {
                  filteredSales[i].delivered = newValue!;
                });
                updateSale(
                    context, filteredSales[i].id, {"delivered": newValue!});
              }),
              activeColor: Theme.of(context).colorScheme.primary,
            ),
          ),
          TableCell(
            verticalAlignment: TableCellVerticalAlignment.middle,
            child: Checkbox(
              value: filteredSales[i].receipted,
              onChanged: ((newValue) {
                setState(() {
                  filteredSales[i].receipted = newValue!;
                });
                updateSale(
                    context, filteredSales[i].id, {"receipted": newValue!});
              }),
              activeColor: Theme.of(context).colorScheme.primary,
            ),
          ),
        ]);
  }
}

销售登记表:

import 'package:ame/services/saleServices.dart';
import 'package:flutter/material.dart';

class SalesEntryForm extends StatefulWidget {
  SalesEntryForm({super.key, required this.date});

  int date;

  @override
  State<SalesEntryForm> createState() => _SalesEntryFormState();
}

class _SalesEntryFormState extends State<SalesEntryForm> {
  static final _formKey = GlobalKey<FormState>();
  var saleService = SaleServices();

  final TextEditingController _contactController = TextEditingController();
  final TextEditingController _amountController = TextEditingController();
  final TextEditingController _descriptionController = TextEditingController();

  Future<void> addNewSale() async {
    try {
      var resposne = await saleService.insertNewSale(context, {
        "date": widget.date,
        "contact": _contactController.text.trim(),
        "amount": int.parse(_amountController.text.trim()),
        "description": _descriptionController.text.trim()
      });
    } catch (e) {
      print(e);
    } finally {
      _formKey.currentState?.reset();
    }
  }

  @override
  Widget build(BuildContext context) {
    var heightVariable = MediaQuery.of(context).size.height;
    return SizedBox(
      height: heightVariable * 0.5,
      width: heightVariable * 0.7,
      child: Form(
          key: _formKey,
          child: SizedBox(
            height: MediaQuery.of(context).size.height * 0.2,
            child: Column(
              children: [
                Row(
                  mainAxisAlignment: MainAxisAlignment.spaceBetween,
                  children: [
                    Expanded(
                      child: Container(
                        margin: const EdgeInsets.all(10.0),
                        child: TextFormField(
                          decoration: InputDecoration(
                              labelText: "Contact",
                              focusedBorder: OutlineInputBorder(
                                  borderSide: BorderSide(
                                      color: Theme.of(context)
                                          .colorScheme
                                          .primary),
                                  borderRadius: BorderRadius.zero),
                              enabledBorder: const OutlineInputBorder(
                                  borderSide: BorderSide(color: Colors.grey),
                                  borderRadius: BorderRadius.zero)),
                          controller: _contactController,
                        ),
                      ),
                    ),
                    Expanded(
                      child: Container(
                        margin: const EdgeInsets.all(10.0),
                        child: TextFormField(
                          decoration: InputDecoration(
                              labelText: "Amount",
                              focusedBorder: OutlineInputBorder(
                                  borderSide: BorderSide(
                                      color: Theme.of(context)
                                          .colorScheme
                                          .primary),
                                  borderRadius: BorderRadius.zero),
                              enabledBorder: const OutlineInputBorder(
                                  borderSide: BorderSide(color: Colors.grey),
                                  borderRadius: BorderRadius.zero)),
                          controller: _amountController,
                        ),
                      ),
                    ),
                  ],
                ),
                Expanded(
                  child: Container(
                    margin: const EdgeInsets.all(10.0),
                    child: TextFormField(
                      decoration: InputDecoration(
                          labelText: "Description",
                          focusedBorder: OutlineInputBorder(
                              borderSide: BorderSide(
                                  color: Theme.of(context).colorScheme.primary),
                              borderRadius: BorderRadius.zero),
                          enabledBorder: const OutlineInputBorder(
                              borderSide: BorderSide(color: Colors.grey),
                              borderRadius: BorderRadius.zero)),
                      controller: _descriptionController,
                      maxLines: 20,
                    ),
                  ),
                ),
                Row(
                  mainAxisAlignment: MainAxisAlignment.end,
                  children: [
                    Container(
                      margin: const EdgeInsets.all(10.0),
                      child: ElevatedButton(
                          style: ElevatedButton.styleFrom(
                            shape: const BeveledRectangleBorder(),
                            padding: const EdgeInsets.symmetric(
                                vertical: 16.0, horizontal: 20.0),
                          ),
                          onPressed: () {
                            addNewSale();
                          },
                          child: const Text("Add")),
                    ),
                  ],
                )
              ],
            ),
          )),
    );
  }
}
5vf7fwbs

5vf7fwbs1#

您应该向SalesEntryForm中注入一个回调,以更新您的销售列表,因此在try/catch中,在var response = await saleService.insertNewSale(...之后,您使用销售示例调用此回调,我不知道您是否可以使用这些数据进行销售,或者响应中是否包含销售示例。

相关问题