Удалить индексный CustomWidget из списка<Widget> во флаттере

У меня изначально пустой список виджетов в колонке. Теперь на другом виджете нажмите Я добавляю новый пользовательский виджет в _contactItems

   Column(
      children: _contactItems,
    )

 List<Widget> _contactItems = new List<CustomWidget>();



 _contactItems.add(newCustomWidget(value));

Теперь предположим, что у меня есть 6 записей (6 пользовательских виджетов в столбце). Я пытаюсь удалить индексные записи (Пример. Я удаляю 3-ю запись, затем 1-ю запись. Виджеты столбцов (динамические виджеты) должны обновляться как _contactItems, обновляемые в setState())

Теперь при нажатии CustomWidget я удаляю этот конкретный CustomWidget из столбца.

setState(() {
          _contactItems.removeAt(index);
        });

Также пробовал с

_contactItems.removeWhere((item) {
            return item.key == _contactItems[index].key;
          });

1 ответ

Решение

Попробуйте это (при условии, что ключи виджета Column имеют такой формат):

setState(() {
  this._contactItems.removeWhere((contact) => contact.key == Key("index_$index"));
});

Если это не решит вашу проблему, возможно, нам понадобится дополнительная информация.

Если вы хотите управлять ListView или GridView, важно назначить ключ каждому дочернему виджету List/GridView.

Короче говоря, Flutter сравнивает виджеты только по типу, а не по состоянию. Таким образом, когда изменяется состояние списка, представленного в List/GridView, Flutter не знает, какие дочерние элементы должны быть удалены, поскольку их типы остаются прежними и проверяются. Единственная проблема, которую подхватывает Flutter, - это количество элементов, поэтому он удаляет только последний виджет в List/GridView.

Поэтому, если вы хотите управлять списками во Flutter, назначьте ключ виджету верхнего уровня каждого дочернего элемента. Более подробное объяснение доступно в этой статье.

Этого можно добиться, добавив

   return GridView.count(
  shrinkWrap: true,
  crossAxisCount: 2,
  crossAxisSpacing: 5.0,
  mainAxisSpacing: 5.0,
  children: List.generate(urls.length, (index) {
    //generating tiles with from list
    return   GestureDetector(
        key: UniqueKey(), //This made all the difference for me
        onTap: () => {
          setState(() {
            currentUrls.removeAt(index); // deletes the item from the gridView
          }) 

        },
        child: FadeInImage( // A custom widget I made to display an Image from 
            image:  NetworkImage(urls[index]),
            placeholder: AssetImage('assets/error_loading.png') 
            ),

    );
  }),

);
Другие вопросы по тегам