2

I am have an animated list in my flutter project.

For every element in that list I have a grid of buttons that are placed dynamically from a Firestore stream. Sometimes that will come back with 10 items in the grid but other times that will comeback with 0 items.

When a button on the grid in a list element is pushed it will search firestore and create a new grid of buttons in the next list element below.

The problem that I have is when it comes back with 0 grid buttons I don't want it to create a new list element (an empty list element with no grid buttons). I tried returning a container with 0 size as a work around but animated list still gives it some height so you can see there is a problem. I also understand that this would be bad practice as you have non visible empty list elements in the list.

I start with a list of foods as strings:

  List foodListGrids = ['breads','drinks']

I then have an animated list:

AnimatedList(
  shrinkWrap: true,
  physics: NeverScrollableScrollPhysics(),
  key: _FoodandDrinkKey,
  initialItemCount: foodListGrids.length,
  itemBuilder: (context, index, animation) {
        return SizeTransition(
                   sizeFactor: animation,
                   child: buildButtonGridItemsMenu(index),
             );
        },
   ),

I set the AnimatedList size to the length of the foods list.

I set the child of the Animated List to a class that searches firebase and returns a card with the grid of buttons on it like this:

StreamBuilder(
        stream: Firestore.instance
            .collection(widget.categoryType)
            .where(widget.relationship, isEqualTo: widget.searchString)
            .snapshots(),
        builder: (BuildContext context, AsyncSnapshot snapshot) {
          if (!snapshot.hasData) {
            return Container(width: 0, height: 0,);
          } else if (snapshot.hasData) {
            List<Widget> widgetList = [];
            List<DocumentSnapshot> documentList = snapshot.data.documents;
            if (documentList.length > 0) {
              for (int i = 0; i < documentList.length; i++) {
                widgetList.add(ButtonTheme(
                  minWidth: 16,
                  height: 30,
                  child: GridButton(snapshot, i, widget.listIndex),
                ));
              }
              return Container(
                  width: double.infinity,
                  child: Wrap(
                    children: widgetList,
                    alignment: WrapAlignment.center,
                  ));
            } else{
              return Text('NO DATA BECAUSE NUMBER OF GRID ITEMS IS 0');
            }
          } else {
            return Text('NO DATA BECAUSE GRID ITEMS CALL IS NULL');
          }
        },
      ),

then in the on pressed method for each grid button I add a new list element like this:

void _insertCategoryGridItem(String id, int index) {
  if (!foodListGrids.contains(id)) {
    foodListGrids.add(id);
    _FoodandDrinkKey.currentState.insertItem(index + 1);
  }
}

The problem is a chicken or the egg problem I will try to show below:

  1. List item is generated from the index 0 in the food list and all stream data is if from food list index 0 firebase results.
  2. On pressed for a grid item in the first list row is pressed to add a new list row with a new set of grid items. This will then update the food list array and the call for the list to add new row of grid buttons. The issue is because this is in the onpressed for the first rows grid there is no knowledge of what will be returned for the next row so there is no way of knowing if it will return a grid of size 0 in the next list row in the current way it is setup.

I have tried returning null, container of 0 width and height but have had no luck. I am not sure what I can do to fix it.

Thanks for your help

4

1 回答 1

1

我不确定我是否正确,但似乎我在使用AnimatedListFirestore 的数据流和数据流时遇到了同样的问题。问题initialItemCount:出在AnimatedList.

就我而言,我想通过AnimtedList两种方式进行更改:

  1. 我想手动添加一个项目并用动画显示它。
  2. 我希望如果由于流中的新数据部分而更改了列表-我希望更新列表时没有插入动画并且没有错误(超出范围)。

为了解决这个问题,我做了一个肮脏的黑客攻击:当流中有更新时,我重新初始化列表的键,在你的情况下它是_FoodandDrinkKey. 因此,在您构建 AnmatedList 之前,只需重新初始化您的密钥_listKeyUserNotes = GlobalKey();,这就是 List 如何“忘记”它的initialItemCount方式,并将呈现新数据而不会出现任何超出范围的错误。当您想使用动画手动添加新项目时,请使用insert()

key: _FoodandDrinkKey,
initialItemCount: foodListGrids.length,

希望这是有道理的。

于 2019-11-23T13:29:12.823 回答