Flutter在For循环中删除多个列表项(For循环中有多个返回)

时间:2019-06-26 13:48:49

标签: flutter dart return flutter-listview

我有一份食物清单。该类别具有subCategory1,subCategory2等。

当用户取消选择类别项目时。他们还取消选择subCategory1,subCatategory2等项目,因为它们是原始类别的子项,如下所示:

enter image description here

enter image description here

enter image description here

所以我有一个for循环,它通过查找子类别列表元素并像这样删除它们来运行:

  // Remove a category item and all of its children
  if (categoryType == "category") {
    List<String> subCategory1Children = List<String>.from(
        snapshot.data.documents[gridIndex]['subCategory1Children']);

    // Remove the subcategory items
    for (int i = 0; i < foodDrinkMenuElements['subCategory1'].length; i++) {
      String subID = foodDrinkMenuElements['subCategory1'][i];
      int removalIndex = _indexOfListGridElement('subCategory1', subID);

      if (subCategory1Children.contains(subID)) {
        _removeCategoryGridItem(removalIndex, subID, 'subCategory1');
      }
    }

    //Remove the actual item being pressed
    _removeCategoryGridItem(listIndex + 1, id, categoryType);
  }

这样调用_removeCategoryGridItem():

void _removeCategoryGridItem(int removalIndex, String id, String categoryType) {
  _FoodandDrinkKey.currentState.removeItem(removalIndex,
      (BuildContext context, Animation<double> animation) {
    return _buildListItem(removalIndex, animation);
  });
  foodDrinkMenuElements[categoryType].remove(id);
}

在删除1个列表项之后,For循环总是结束。我认为这是由于函数_removeCategoryGridItem中的return语句引起的。

我还看到了其他答案,说要把它放在列表中并遍历整个列表,但我看不出这在这里如何适用。

感谢您的帮助

1 个答案:

答案 0 :(得分:1)

  

在删除1个列表项之后,For循环总是结束。我认为这是由于函数_removeCategoryGridItem中的return语句引起的。

不,通常,函数可以在调用函数中跳出循环的唯一方法是抛出异常。

我不知道返回的类型是foodDrinkMenuElements[categoryType],但是假设它是ListMapSet,则不能从集合在遍历集合时。

来自List documentation

  

在执行列表操作时,通常不允许修改列表的长度(添加或删除元素)。...在迭代过程中更改列表的长度...会中断迭代。 / p>

MapSet有相似的语言。

  

我还看到了其他答案,说要把它放在列表中并遍历整个列表,但我看不出这在这里如何适用。

这正是您应该做的:您应该排队要删除哪些项目,然后处理队列以避免变异您要遍历的同一集合:

final pendingRemoves = List<void Function()>[];

// Remove the subcategory items
for (int i = 0; i < foodDrinkMenuElements['subCategory1'].length; i++) {
  String subID = foodDrinkMenuElements['subCategory1'][i];
  int removalIndex = _indexOfListGridElement('subCategory1', subID);

  if (subCategory1Children.contains(subID)) {
    pendingRemoves.add(() =>
        _removeCategoryGridItem(removalIndex, subID, 'subCategory1'));
  }
}

// Since an index is involved, you also need to remove in reverse order so that
// the queued indices still refer to the same elements.
for (pendingRemove in pendingRemoves.reversed) {
  pendingRemove();
}

//Remove the actual item being pressed
_removeCategoryGridItem(listIndex + 1, id, categoryType);