ListView не обновляется после нажатия GesutreDetector

#flutter #mobile-development

Вопрос:

Мое представление списка не обновляется после того, как я нажимаю на свою кнопку, даже несмотря на то, что вызов функции (fillPickupList) заполняет массив данными, представление списка по-прежнему ничего не отображает, я даже проверил размер массива после асинхронного вызова функции (fillpickupList), размер говорит 1. Но когда я перезагружаю приложение, используя горячую загрузку, оно временно отображает данные перед перезагрузкой приложения, оно также делает то же самое, когда я запускаю приложение.

 class OrdersPage extends StatefulWidget {
  final String coursecode;

  const OrdersPage({Key? key, required this.coursecode}) : super(key: key);

  @override
  _OrdersPageState createState() => _OrdersPageState();
}

class _OrdersPageState extends State<OrdersPage> {
  List<OrdersClass> pendingList = [];
  List<OrdersClass> clearedList = [];
  bool showPendingPickups = true;
  // Map<String,dynamic> eachDocument = {};

  void fillPickupList() async {
    pendingList = [];
    print("size of pending list ${pendingList.length}"); //this prints out zero
    await FirebaseFirestore.instance
        .collection('Computer science')
        .doc("orders")
        .collection(widget.coursecode.replaceAll(" ", "").trim().toLowerCase())
        .get()
        .then(
            (QuerySnapshot querySnapshot) => querySnapshot.docs.forEach((doc) {
                  Map<String, dynamic> eachDocument =
                      doc.data() as Map<String, dynamic>;
                  (eachDocument.isEmpty)
                      ? print(doc.id)
                      : this.pendingList.add(OrdersClass(
                          firstname: eachDocument["firstname"],
                          lastname: eachDocument["lastname"],
                          matnumber: eachDocument["matnumber"],
                          id: eachDocument["id"],
                          date: eachDocument["date"],
                          documentId: doc.id,
                          pending: true));
                }));
    print(
        "in pending list .. ${pendingList.first.firstname}"); //This prints out the firstname
  }

  void fillClearedList() async {
    // print (widget.coursecode.replaceAll(" ", "").trim().toLowerCase());
    await FirebaseFirestore.instance
        .collection('Computer science')
        .doc("clearedorders")
        .collection(widget.coursecode.replaceAll(" ", "").trim().toLowerCase())
        .get()
        .then(
            (QuerySnapshot querySnapshot) => querySnapshot.docs.forEach((doc) {
                  Map<String, dynamic> eachDocument =
                      doc.data() as Map<String, dynamic>;
                  (eachDocument.isEmpty)
                      ? print(doc.id)
                      : clearedList.add(OrdersClass(
                          firstname: eachDocument["firstname"],
                          lastname: eachDocument["lastname"],
                          matnumber: eachDocument["matnumber"],
                          id: eachDocument["id"],
                          date: eachDocument["date"],
                          documentId: doc.id,
                          pending: true));
                  // print (doc.id);
                }));
  }

  @override
  void initState() {
    // TODO: implement initState
    super.initState();
    FirebaseFirestore.instance;

    // fillPickupList();
    // fillClearedList();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(),
      body: Container(
        child: Column(
          children: [
            Container(
              height: 100,
              child: GridView.count(crossAxisCount: 2, children: [
                GestureDetector(
                  onTap: () {
                    setState(() {
                      this.showPendingPickups = true;
                      // pendingList = [];
                    });
                    fillPickupList();
                  },
                  child: Card(
                    child: Center(
                      child: Text(
                        "Pending Pickups",
                        style: TextStyle(
                            fontSize: 20,
                            fontStyle: FontStyle.italic,
                            color: Colors.blue),
                      ),
                    ),
                  ),
                ),
                GestureDetector(
                  onTap: () {
                    setState(() {
                      showPendingPickups = false;
                    });
                    fillClearedList();
                  },
                  child: Card(
                    child: Center(
                      child: Text(
                        "Picked Up",
                        style: TextStyle(
                            fontSize: 20,
                            fontStyle: FontStyle.italic,
                            color: Colors.blue),
                      ),
                    ),
                  ),
                )
              ]),
            ),
            Padding(padding: EdgeInsets.only(bottom: 15)),
            (showPendingPickups)
                ? Text(
                    //prints this successfully
                    "Pending Pickups ",
                    style: TextStyle(
                      fontStyle: FontStyle.italic,
                      fontWeight: FontWeight.bold,
                      decoration: TextDecoration.underline,
                    ),
                  )
                : Text(
                    "Cleared Pickups",
                    style: TextStyle(
                      fontStyle: FontStyle.italic,
                      fontWeight: FontWeight.bold,
                      decoration: TextDecoration.underline,
                    ),
                  ),
            Padding(padding: EdgeInsets.only(bottom: 5)),
            (this.showPendingPickups)
                ? Container(
                    //does not print this on button tap.
                    //make this dynamic
                    height: 300,
                    child: ListView.separated(
                        itemBuilder: (context, index) {
                          // return ListTile(
                          //   leading:
                          //       Text("the $index"), //pendingList[index].date
                          //   title: Text(pendingList[index].firstname  
                          //       " "  
                          //       pendingList[index].lastname  
                          //       "n"  
                          //       pendingList[index].matnumber),
                          //   subtitle: Text("userid: "   pendingList[index].id),
                          //   trailing: ElevatedButton(
                          //     onPressed: () async {
                          //       // moveUserToPickedUp(
                          //       //     index: index, date: pendingList[index].date, firstname: pendingList[index].firstname,
                          //       //     documentID: pendingList[index].documentId,
                          //       //     id: pendingList[index].id, lastname: pendingList[index].lastname,
                          //       //     matnumber: pendingList[index].matnumber);
                          //       // setState(() {
                          //       //
                          //       // });
                          //     },
                          //     child: Text("PickedUp"),
                          //   ),
                          // );
                          return Text("the $index");
                        },
                        separatorBuilder: (context, index) {
                          return Divider();
                        },
                        itemCount: pendingList.length),
                  )
                : Container(
                    height: 300,
                    child: ListView.separated(
                        itemBuilder: (context, index) {
                          return ListTile(
                            leading:
                                Text("cleared list"), //clearedList[index].date
                            title: Text(clearedList[index].firstname  
                                " "  
                                clearedList[index].lastname  
                                "n"  
                                clearedList[index].matnumber),
                            subtitle: Text("userid: "   clearedList[index].id),
                            trailing: ElevatedButton(
                              onPressed: () async {
                                // moveUserToPickedUp(
                                //     index: index, date: pendingList[index].date, firstname: pendingList[index].firstname,
                                //     documentID: pendingList[index].documentId,
                                //     id: pendingList[index].id, lastname: pendingList[index].lastname,
                                //     matnumber: pendingList[index].matnumber);
                                // setState(() {
                                //
                                // });
                              },
                              child: Text("PickedUp"),
                            ),
                          );
                        },
                        separatorBuilder: (context, index) {
                          return Divider();
                        },
                        itemCount: clearedList.length),
                  )
          ],
        ),
      ),
    );
  }
}
 

Ответ №1:

Если ваша цель-получать данные из Firestore, как только новые данные будут добавлены в ваш Firestore, я бы предложил вместо этого использовать Streambuilder. затем вы получите данные, как только они будут записаны в Firestore.

Пример :

      class OrdersPage extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        final user = FirebaseAuth.instance.currentUser!;
    
        return StreamBuilder(
            stream: FirebaseFirestore.instance
                .collection('Computer science')
                .doc('orders')
                .collection('sub-collection')
                .snapshots(),
            builder: (ctx, AsyncSnapshot<QuerySnapshot> ordersSnapshot) {
           
    
              final currentOrders = ordersSnapshot.data!.docs;
    
             ListView.builder(
                  itemCount: currentOrders.length,
                  itemBuilder: (ctx, index) => OrderItem(
                      OrdersClass(
                          firstname: currentOrders[index]["firstname"],
                          lastname: currentOrders[index]["lastname"],
                          matnumber: currentOrders[index]["matnumber"],
                          id: currentOrders[index]["id"],
                          date: currentOrders[index]["date"],
                          documentId: doc.id,
                          pending: true));
                      ),
                    );
            });
      }
    }
 

Комментарии:

1. Спасибо, это даже лучше работает, и еще короче!!.