1

我有一个监听 Firestore 的流构建器,它在获取数据时工作。问题是当我切换页面时流构建器会不断重建。主页面首先构建两次,当我滚动到另一个页面时它再次构建两次,当我弹回主页面时它会第三次重新构建,依此类推。图像存储在临时存储中,我用 AssetImage() 打开它们

这就是我的意思:https ://imgur.com/WMzzb0W

如果您需要参考我遵循的教程: https ://www.youtube.com/watch?v=8PfiY0U_PBI

代码:

void queryItems() async {
    //!Fetch items
    try {
      Query query = await
          yogurts.collection('current_items').where("available", isEqualTo: true);
      //!Filter available izdelke
      //*QuerySnapshot contains zero or more QueryDocumentSnapshot objects representing the results of a query
      items = query.snapshots().map((list) {
        //!Convert stream to map on the fly ->
        return list.documents.map((doc) {
          //*For every document
          return doc.data; //*Data from every document
        });
      });
      _postStreamController.add(items);
    } catch (e) {
      print("Got error: ${e.error}");
    }
  }

  Container buildSelection(BuildContext context) {
    return Container(
            height: MediaQuery.of(context).size.height * 0.9,  //!Višina containerja je 90% višine ekrana
            decoration: new BoxDecoration(
                boxShadow: [
                  new BoxShadow(
                    color: Colors.black.withOpacity(0.6), //*Black shadow okoli
                    offset: new Offset(1.0, 2.0), //*z offsetom
                    blurRadius: 15.0,
                  )
                ],
                color: THEME_COLOR.withOpacity(0.9), //*Tema
                borderRadius: new BorderRadius.only(
                    //*Oglati robovi
                    bottomLeft: const Radius.circular(55.0),
                    bottomRight: const Radius.circular(55.0))),
            child: Column(
              crossAxisAlignment: CrossAxisAlignment.center,
              mainAxisSize: MainAxisSize.max,
              mainAxisAlignment: MainAxisAlignment.start,
              children: <Widget>[
                Padding(
                  //!Vrsta za orders in settings icone
                  padding: const EdgeInsets.only(left: 20, right: 20, top: 25),
                  child: Row(
                    mainAxisSize: MainAxisSize.max,
                    mainAxisAlignment: MainAxisAlignment
                        .spaceBetween, //!Porazdeli ikone levo in desno z spaco-om vmes
                    children: <Widget>[
                      new OrdersIcon(user: user),
                      new SettingsIcon(user: user),
                    ],
                  ),
                ),
                //!Stream builder za grajenje seznama izdelkov iz baze
                StreamBuilder(
                  //!Posluša in rebuilda seznam for every new event
                  stream: items, //?single-subscription stream from the future
                  initialData: [],
                  builder: (context, AsyncSnapshot snap) {
                    //*Rebuilds its childer whenever a new value gets emited by the stream
                    List slideList =
                        snap.data.toList(); //! Convert AsynSnapshot into List
                    print("Number of all items:" + slideList.length.toString());
                    if (snap.connectionState == ConnectionState.waiting) {
                      return Center(
                        child: CircularProgressIndicator(
                          valueColor: AlwaysStoppedAnimation<Color>(Colors.white),
                        ),
                      );
                    } else {
                      return Container(
                        height: MediaQuery.of(context).size.height * 0.7,
                        child: PageView.builder(
                            onPageChanged: (num) {
                              print("Current index: " + num.toString());
                            },
                            controller: itemView, //!Pass PageView controller
                            scrollDirection: Axis.horizontal,
                            itemCount: slideList.length, //!Število elementov je dolžina lista
                            itemBuilder: (context, int currentIndex) {
                              //!Build current facing item
                              bool active = (currentIndex == current_page);
                              //print(active.toString());
                              //print("Trenutni index: " + currentIndex.toString() + " Trenutna stran: " + current_page.toString());
                              //?(Lastnosti izdelka kot Map, bool trenutno aktiven, trenutni facing element)
                              return buildProductListPage(slideList[currentIndex], active, currentIndex);
                            },
                          ),
                      );
                    }
                  },
                ),

              ],
            ),
          );
  }

  //!Build list view of products
  Widget buildProductListPage(Map data, bool active, var index) {
    final double blur = active ? 5 : 0;
    final double offset = active ? 2 : 0;
    final double top = active ? 30 : 200;
    final double iconSize = active ? 50 : 0;
    final String ime = data['file_name'];
    final String path = "${dir.path}/$ime";
    print(path);
    return AnimatedContainer(
      height: 600,
      width: 400,
      duration: Duration(milliseconds: 1200),
      curve: Curves.easeOutQuint,
      margin: EdgeInsets.only(top: top, bottom: 10, right: 15, left: 15),
      decoration: BoxDecoration(
          borderRadius: BorderRadius.circular(20.0),
          image: DecorationImage(
              fit: BoxFit.cover, image: AssetImage(path)),
          boxShadow: [
            BoxShadow(
              color: Colors.black.withOpacity(0.7),
              offset: new Offset(offset / 2, offset),
              blurRadius: blur,
            )
          ]),
      child: Stack(
        children: <Widget>[
          Column(
            children: <Widget>[
              Align(
                alignment: Alignment.topCenter,
                child: Padding(
                  padding: const EdgeInsets.only(top: 15.0),
                  child: Text(
                    data['ime'],
                    style: TextStyle(
                        fontFamily: 'MadeEvolveSans', fontSize: 50, color: WHITE),
                  ),
                ),
              ),
              Align(
                alignment: Alignment.topCenter,
                child: Text(
                  data['volume'].toString() + "ml",
                  style:
                      TextStyle(fontFamily: 'MadeEvolveSans', fontSize: 25, color: WHITE),
                ),
              ),
            ],
          ),
          Align(
            alignment: Alignment.bottomRight,
            child: Padding(
              padding: const EdgeInsets.only(bottom: 15.0, right: 17.0),
              child: IconButton(
                onPressed: () {
                  setState(() {
                    if (selectedItems.containsKey(data['ime'])) {
                      selectedItems.update(data['ime'], (dynamic val) => ++val);
                    } else {
                      selectedItems[data['ime']] = 1;
                    }
                    print(selectedItems);
                  });
                },
                icon: Icon(
                  Icons.add_circle,
                  color: WHITE,
                  size: iconSize,
                ),
              ),
            ),
          ),
          Align(
            alignment: Alignment.bottomCenter,
            child: Padding(
              padding: const EdgeInsets.only(bottom: 0.0),
              child: Text(
                (selectedItems[data['ime']] == 0 || selectedItems[data['ime']] == null)
                    ? " "
                    : selectedItems[data['ime']].toString(),
                style:
                    TextStyle(fontFamily: 'MadeEvolveSans', fontSize: 60, color: WHITE),
              ),
            ),
          ),
          Align(
            alignment: Alignment.bottomLeft,
            child: Padding(
              padding: const EdgeInsets.only(bottom: 15.0, left: 0.0),
              child: IconButton(
                onPressed: () {
                  setState(() {
                    if (selectedItems.containsKey(data['ime'])) {
                      selectedItems.update(data['ime'], (dynamic val) => --val);
                      if (selectedItems[data['ime']] == 0) {
                        selectedItems.remove(data['ime']);
                      }
                    }
                    print(selectedItems);
                  });
                },
                icon: Icon(
                  Icons.do_not_disturb_on,
                  color: WHITE,
                  size: iconSize,
                ),
              ),
            ),
          ),
        ],
      ),
    );
  }

任何帮助将不胜感激:D

4

1 回答 1

0

StreamBuilder 仅在它正在侦听的 Stream 已更新时重建。您可能想了解 Streamitems是如何更新或初始化的。您可能会在滚动期间更新 Stream,这会导致 StreamBuilder 重建。

于 2021-09-22T02:48:20.390 回答