Flutter动画列表:有条件地添加ListView项

时间:2019-06-10 14:06:56

标签: flutter flutter-listview

我的flutter项目中有一个动画列表。

对于该列表中的每个元素,我都有一个按钮网格,这些按钮从Firestore流中动态放置。有时,它将在网格中返回10个项目,而在其他时候,将返回0个项目。

当按下列表元素中网格上的按钮时,它将搜索Firestore并在下面的下一个列表元素中创建新的按钮网格。

我遇到的问题是当它返回0个网格按钮时,我不希望它创建一个新的列表元素(一个没有网格按钮的空列表元素)。我尝试返回大小为0的容器,但动画列表仍然为它提供了一定的高度,因此您可以看到有问题。我也了解这是不好的做法,因为列表中有不可见的空列表元素。

我从食物列表开始:

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

然后我有一个动画列表:

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

我将AnimatedList的大小设置为食物列表的长度。

我将“动画列表”的子级设置为搜索firebase并返回带有其上的按钮网格的卡片的类:

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');
          }
        },
      ),

然后在每个网格按钮的按下方法中,我添加一个新的列表元素,如下所示:

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

问题是鸡肉或鸡蛋问题,我将尝试在下面显示:

  1. 列表项是从食物列表的索引0生成的,并且所有流数据都是从食物列表索引0的Firebase结果生成的。
  2. 在按下第一条列表行中的网格项时,将按下以添加具有一组新的网格项的新列表行。然后,这将更新食物列表数组和对列表的调用以添加新的网格按钮行。问题是因为这在第一行网格的onpressed中不知道下一行将返回什么,因此无法知道是否会在列表的下一个列表行中返回大小为0的网格。当前的设置方式。

我尝试返回宽度为0且高度为0的null,但是没有运气。我不确定该如何解决。

感谢您的帮助

1 个答案:

答案 0 :(得分:0)

我不确定我是否正确,但是似乎Bundle b = getIntent().getExtras(); age.setText(b.getCharSequence("age")); int checked = b.getInt("checked"); if (checked==1){ // male jk.setText("male"); int theage = Integer.parseInt(age.getText().toString()); int HRmax = 220 - theage; hrmax.setText(String.valueOf(HRmax)); } else {// female jk.setText("female"); int theage = Integer.parseInt(age.getText().toString()); int HRmax = 226 - theage; hrmax.setText(String.valueOf(HRmax)); } 和Firestore的数据流遇到了同样的问题。问题出在AnimatedList的{​​{1}}属性中。

就我而言,我想通过两种方式更改initialItemCount:

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

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

initialItemCount

希望这是有道理的。